From bfa813fcb15093aac035e61d2c7063f859629e39 Mon Sep 17 00:00:00 2001 From: Patrick Vogler Date: Tue, 20 Jun 2023 13:43:33 +0200 Subject: [PATCH] Initial commit --- .gitignore | 271 ++ CMakeLists.txt | 184 + LICENSE | 9 + Makefile | 198 + README.md | 43 + docs/img/Logo.png | Bin 0 -> 1328942 bytes docs/templates/header.h | 299 ++ docs/templates/source.c | 179 + include/interfaces/reader/eas3.h | 336 ++ include/library/private/bitstream.h | 224 + include/library/private/codestream.h | 191 + include/library/private/constants.h | 328 ++ include/library/private/dwt.h | 328 ++ include/library/private/libbwc.h | 394 ++ include/library/private/macros.h | 140 + include/library/private/mq.h | 155 + include/library/private/mq_types.h | 222 + include/library/private/prim_types_double.h | 163 + include/library/private/prim_types_single.h | 163 + include/library/private/tagtree.h | 161 + include/library/private/tier1.h | 153 + include/library/private/tier2.h | 133 + include/library/private/types.h | 1805 ++++++++ include/tools/bwccmdl.h | 350 ++ public_header.py | 331 ++ src/interfaces/python/bwc.py | 221 + src/interfaces/reader/eas3.c | 1127 +++++ src/library/CMakeLists.txt | 126 + src/library/bitstream.c | 1021 ++++ src/library/codestream.c | 1824 ++++++++ src/library/dwt.c | 2681 +++++++++++ src/library/libbwc.c | 4600 +++++++++++++++++++ src/library/mq.c | 1196 +++++ src/library/tagtree.c | 594 +++ src/library/tier1.c | 3381 ++++++++++++++ src/library/tier2.c | 1704 +++++++ src/tools/CMakeLists.txt | 93 + src/tools/bwccmdl.c | 3243 +++++++++++++ src/tools/get_hash.c | 154 + 39 files changed, 28725 insertions(+) create mode 100644 .gitignore create mode 100755 CMakeLists.txt create mode 100644 LICENSE create mode 100755 Makefile create mode 100644 README.md create mode 100644 docs/img/Logo.png create mode 100755 docs/templates/header.h create mode 100755 docs/templates/source.c create mode 100644 include/interfaces/reader/eas3.h create mode 100755 include/library/private/bitstream.h create mode 100755 include/library/private/codestream.h create mode 100755 include/library/private/constants.h create mode 100755 include/library/private/dwt.h create mode 100755 include/library/private/libbwc.h create mode 100755 include/library/private/macros.h create mode 100755 include/library/private/mq.h create mode 100755 include/library/private/mq_types.h create mode 100755 include/library/private/prim_types_double.h create mode 100755 include/library/private/prim_types_single.h create mode 100755 include/library/private/tagtree.h create mode 100755 include/library/private/tier1.h create mode 100755 include/library/private/tier2.h create mode 100755 include/library/private/types.h create mode 100644 include/tools/bwccmdl.h create mode 100644 public_header.py create mode 100644 src/interfaces/python/bwc.py create mode 100644 src/interfaces/reader/eas3.c create mode 100755 src/library/CMakeLists.txt create mode 100755 src/library/bitstream.c create mode 100755 src/library/codestream.c create mode 100755 src/library/dwt.c create mode 100755 src/library/libbwc.c create mode 100755 src/library/mq.c create mode 100755 src/library/tagtree.c create mode 100755 src/library/tier1.c create mode 100755 src/library/tier2.c create mode 100755 src/tools/CMakeLists.txt create mode 100755 src/tools/bwccmdl.c create mode 100755 src/tools/get_hash.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c04684b --- /dev/null +++ b/.gitignore @@ -0,0 +1,271 @@ +# ---> C +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +# ---> CMake +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps + +# ---> Fortran +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# ---> Python +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +bin/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +include/library/public +lib/ +lib64/ +out/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# Files and Archives +.eas +.npz +.zip + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints +.ipynb + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..64b7c50 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,184 @@ +#*====================================================================================================================*# +#| |# +#| /$$$$$$$ /$$ /$$ /$$ /$$ |# +#| | $$__ $$|__/ | $$ /$ | $$| $$ |# +#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# +#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# +#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# +#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# +#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# +#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# +#| /$$ \ $$ | $$ |# +#| | $$$$$$/ | $$ |# +#| \______/ |__/ |# +#| DESCRIPTION: |# +#| ------------ |# +#| Defines the global cmake script for the Big Whoop compression algorithm. |# +#| |# +#| |# +#| DEVELOPMENT HISTORY: |# +#| -------------------- |# +#| |# +#| Date Author Change Id Release Description Of Change |# +#| ---- ------ --------- ------- --------------------- |# +#| 30.08.2018 Patrick Vogler B87D120 V 0.1.0 Cmake file created |# +#| |# +#| |# +#| ------------------------------------------------------------------------------------------------------ |# +#| |# +#| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart |# +#| |# +#| Redistribution and use in source and binary forms, with or without modification, are permitted |# +#| provided that the following conditions are met: |# +#| |# +#| (1) Redistributions of source code must retain the above copyright notice, this list of |# +#| conditions and the following disclaimer. |# +#| |# +#| (2) Redistributions in binary form must reproduce the above copyright notice, this list |# +#| of conditions and the following disclaimer in the documentation and/or other materials |# +#| provided with the distribution. |# +#| |# +#| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED |# +#| WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |# +#| PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR |# +#| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |# +#| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |# +#| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR |# +#| TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |# +#| ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |# +#| |# +#*====================================================================================================================*# +#*--------------------------------------------------------*# +# Check if the version requirement for cmake is met. # +#*--------------------------------------------------------*# +cmake_minimum_required(VERSION 3.5.1) + +#*--------------------------------------------------------*# +# Set the project name and description. # +#*--------------------------------------------------------*# +project(BWC LANGUAGES C) +set(PROJECT_DESCRIPTION "Compression algorithm for IEEE 754 datasets") + +#*--------------------------------------------------------*# +# Check that the current build is not a in-source build. # +#*--------------------------------------------------------*# +if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) + message(FATAL_ERROR "In-source builds are prohibited. Please create a separate build directory") +endif() + +#*--------------------------------------------------------*# +# Save the bwc.c file in a temporary variable and match # +# the current version number with a regular expression. # +#*--------------------------------------------------------*# +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/src/library/libbwc.c _bwc_c_contents) +string(REGEX MATCH "Version[ \t]+([0-9]+).([0-9]+).([0-9]+)" _ ${ver} ${_bwc_c_contents}) +set(BWC_VERSION_MAJOR ${CMAKE_MATCH_1}) +set(BWC_VERSION_MINOR ${CMAKE_MATCH_2}) +set(BWC_VERSION_PATCH ${CMAKE_MATCH_3}) +set(BWC_VERSION "${BWC_VERSION_MAJOR}.${BWC_VERSION_MINOR}.${BWC_VERSION_PATCH}") + +#*--------------------------------------------------------*# +# Setup a user-specified option used to control the sample # +# precision during compression. The standard option is # +# set to double precision. # +#*--------------------------------------------------------*# +set(PREC "Double" CACHE STRING "User-specified option used to control\ + the precision during compression") + +#*--------------------------------------------------------*# +# Inlude the GNU standard installation directories module # +# to set up the output directories. # +#*--------------------------------------------------------*# +include(GNUInstallDirs) + +#*--------------------------------------------------------*# +# Set up the output directories for the Big Whoop library # +# and utility binaries. # +#*--------------------------------------------------------*# +list(INSERT CMAKE_MODULE_PATH 0 "${BWC_SOURCE_DIR}/cmake") +if(${TOOL}) + if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BWC_SOURCE_DIR}/${CMAKE_INSTALL_BINDIR}) + endif() +endif() +if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${BWC_SOURCE_DIR}/${CMAKE_INSTALL_LIBDIR}) +endif() +if(NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${BWC_SOURCE_DIR}/${CMAKE_INSTALL_LIBDIR}) +endif() + +#*--------------------------------------------------------*# +# Suggest the C standard (C99) used by the compiler. # +#*--------------------------------------------------------*# +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 11) +endif() + +message(STATUS "Compiling with C standard: ${CMAKE_C_STANDARD}") + +#*--------------------------------------------------------*# +# Suggest the C++ standard (CXX98) used by the compiler. # +#*--------------------------------------------------------*# +# Suggest C++98 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 11) +endif() + +message(STATUS "Compiling with C++ standard: ${CMAKE_CXX_STANDARD}") + +#*--------------------------------------------------------*# +# Check if the OpenMP package is available for the current # +# setup and set the appropriate C/C++ flags. # +#*--------------------------------------------------------*# +if("${CMAKE_BUILD_TYPE}" STREQUAL "Release") + find_package(OpenMP) + if (OPENMP_FOUND) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") + endif() +endif() + +#*--------------------------------------------------------*# +# Add all necessary compiler warnings for debugging. # +#*--------------------------------------------------------*# +if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") +endif() + +#*--------------------------------------------------------*# +# Include the CMake dependent option macro. # +#*--------------------------------------------------------*# +include(CMakeDependentOption) + +#*--------------------------------------------------------*# +# Set the -fPIC compile option for static libraries. # +#*--------------------------------------------------------*# +get_property(SHARED_LIBS_SUPPORTED GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS) +cmake_dependent_option(BUILD_SHARED_LIBS + "Whether or not to build shared libraries" ON + "SHARED_LIBS_SUPPORTED" OFF) + +if(SHARED_LIBS_SUPPORTED) + cmake_dependent_option(BWC_ENABLE_PIC + "Build with Position Independent Code" ON + "NOT BUILD_SHARED_LIBS" ON) +endif() + +if(BWC_ENABLE_PIC) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif() + +#*--------------------------------------------------------*# +# Add the project source code. # +#*--------------------------------------------------------*# +add_subdirectory(src/library) + +#*--------------------------------------------------------*# +# Add the utilities source code if requested. # +#*--------------------------------------------------------*# +if(${TOOL}) + add_subdirectory(src/tools) +endif() \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3903c06 --- /dev/null +++ b/LICENSE @@ -0,0 +1,9 @@ +Copyright (c) 2023, High Performance Computing Center - University of Stuttgart + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Makefile b/Makefile new file mode 100755 index 0000000..71dbbb7 --- /dev/null +++ b/Makefile @@ -0,0 +1,198 @@ +#*====================================================================================================================*# +#| |# +#| /$$$$$$$ /$$ /$$ /$$ /$$ |# +#| | $$__ $$|__/ | $$ /$ | $$| $$ |# +#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# +#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# +#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# +#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# +#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# +#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# +#| /$$ \ $$ | $$ |# +#| | $$$$$$/ | $$ |# +#| \______/ |__/ |# +#| |# +#| |# +#| Version 0.1.0 |# +#| |# +#| DESCRIPTION: |# +#| ------------ |# +#| Defines a wrapper for the Big Whoop cmake & make tools. This Makefile creates the |# +#| build dir if it does not exist, switches to it and executes cmake and make. |# +#| |# +#| ---------------------------------------------------------------------------------------------------------------- |# +#| |# +#| Copyright (c) 2021, High Performance Computing Center - University of Stuttgart |# +#| |# +#| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the |# +#| following conditions are met: |# +#| |# +#| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the |# +#| following disclaimer. |# +#| |# +#| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and |# +#| the following disclaimer in the documentation and/or other materials provided with the distribution. |# +#| |# +#| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED |# +#| WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |# +#| PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY |# +#| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |# +#| PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |# +#| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |# +#| OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |# +#| DAMAGE. |# +#| |# +#*====================================================================================================================*# +#*--------------------------------------------------------*# +# Define special targets for the required build commands. # +#*--------------------------------------------------------*# +.PHONY: clean +.PHONY: help + +.PHONY: static +.PHONY: single + +.PHONY: tool +.PHONY: eas3 +.PHONY: netCDF + +.PHONY: --build_debug + +.PHONY: default +.PHONY: debug +.PHONY: full + +#*--------------------------------------------------------*# +# Initialize the compiler flags used to build the library. # +#*--------------------------------------------------------*# +BUILD_TYPE="Release" + +LINK_TYPE="Dynamic" + +BUILD_PREC="Double" + +BUILD_TOOL="False" + +BUILD_EAS3="False" + +BUILD_NETCDF="False" + +#*--------------------------------------------------------*# +# Define default target. # +#*--------------------------------------------------------*# +default: | build_bwc display + +#*--------------------------------------------------------*# +# Define helper target. # +#*--------------------------------------------------------*# +help: + + @echo "Usage: make [options] [argument] Compile the BigWhoop library using the specified" + @echo " [options] and [argument]. Only one argument is " + @echo " accepted per compile run." + @echo "" + @echo "Arguments:" + @echo "" + @echo " [Type] [Description]" + @echo "" + @echo " debug Compiles BigWhoop and the command line tool with " + @echo " full file support. All relevant debug flags are set." + @echo "" + @echo " full Compiles BigWhoop (with OpenMP enabled if applica-" + @echo " ble) and the command line tool with full file sup-" + @echo " port. Code optimization is set to the highest level." + @echo "" + @echo " clean Removes all files and folders created during a pre-" + @echo " vious compile run." + @echo "" + @echo "Options:" + @echo "" + @echo " [Type] [Description]" + @echo "" + @echo " static Builds BigWhoop as a static library." + @echo "" + @echo " single Compiles the BigWhoop library in single precision" + @echo " mode." + @echo "" + @echo " tool Build the command line tool." + @echo "" + @echo " eas3 Adds support for the eas3 file format to the com-" + @echo " mand line tool." + @echo "" + @echo " netCDF Adds support for the eas3 file format to the com-" + @echo " mand line tool." + +#*--------------------------------------------------------*# +# Define private targets. # +#*--------------------------------------------------------*# +--build_debug: + $(eval BUILD_TYPE="Debug") + +#*--------------------------------------------------------*# +# Define targets used to instrument library properites. # +#*--------------------------------------------------------*# +static: + $(eval LINK_TYPE="Static") + +single: + $(eval BUILD_PREC="Single") + +#*--------------------------------------------------------*# +# Define target used to activate command line tool build. # +#*--------------------------------------------------------*# +tool: + $(eval BUILD_TOOL="True") + + +#*--------------------------------------------------------*# +# Define targets used to activate file format support. # +#*--------------------------------------------------------*# +eas3: + $(eval BUILD_EAS3="True") + +netCDF: + $(eval BUILD_NETCDF="True") + +#*--------------------------------------------------------*# +# Define the wrappers for the compile command targets. # +#*--------------------------------------------------------*# +debug: | clean --build_debug tool eas3 build_bwc display +release: | build_bwc display +full: | clean tool eas3 build_bwc display + +#*--------------------------------------------------------*# +# Define target used to output compile information. # +#*--------------------------------------------------------*# +display: + @echo "==============================================================" + @echo "" + @echo " .:-------------: .:-------------: " + @echo " .+++++++++++++++= :+++++++++++++++- " + @echo " :+++. -++= -++= " + @echo " :+++. -++= -++= " + @echo " -++++++++++++++= -++= -++= " + @echo " .=++---------=++= -++= -++= " + @echo " :+++ :++= -++= -++= " + @echo " .+++=--------=+++---=+++---=+++------------: " + @echo " -=++++++++++++++++++++++++++++++++++++++++- " + @echo "" + @echo "----------------- Successfully Compiled -----------------" + @echo "" + @echo " Build Type: $(BUILD_TYPE)" + @echo " Link Type: $(LINK_TYPE)" + @echo " Precision: $(BUILD_PREC)" + @echo " Utilities: $(BUILD_TOOL)" + @echo "" + @echo " Build date: $(shell date)" + @echo " User: $(USER)" + @echo "" + @echo "==============================================================" + +#*--------------------------------------------------------*# +# Define the main compile command targets. # +#*--------------------------------------------------------*# +build_bwc: + mkdir -p build && cd build && cmake .. "-DCMAKE_BUILD_TYPE=${BUILD_TYPE}" "-DLINK:STRING=${LINK_TYPE}" "-DPREC:STRING=${BUILD_PREC}" "-DTOOL=${BUILD_TOOL}" "-DBUILD_EAS3=${BUILD_EAS3}" "-DBUILD_NETCDF=${BUILD_NETCDF}" && $(MAKE) -j + +clean: + - /bin/rm -rf build/ bin/ lib/ lib64/ include/library/public \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..0d717e9 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +

+ + BigWhoop + +

+

Compression library for numerical datasets

+ + +BigWhoop is a compression library for numerical datasets that has been developed as part of the EU Projects ExaFLOW and EXCELLERAT. It aims to give scientists and egineers a tool to drastically reduce the size of their simulation data while minimizing the distortion introduced by a lossy compression scheme. + + +

Building BigWhoop

+ +### Dependencies + +* make +* cmake (>= 3.5.1) +* gcc (>= 8.5.0) + +### Building + +pull the sources from HLRS' gitea instance (note: default branch is `main`): +``` +git pull https://code.hlrs.de/hpcpvogl/BigWhoop.git +``` + +Now change into the source directory and run the following commands. + +**for a simple build** +``` +make clean +make +``` +**for a full build (including command line tool)** +``` +make full +``` +**for debugging** +``` +make clean +make debug +``` +This builds the library and places the associated files in the `/lib` or `/lib64` folders. If a full build was attempted, the command line tool binaries are placed in the `/bin` folder. diff --git a/docs/img/Logo.png b/docs/img/Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..140bbcdae23a65b8d7948c8b1a351abdfdd5dac6 GIT binary patch literal 1328942 zcmdRVXH-+$7A`gv!2(EEKtw=5LNB32kRno*-lYZzMF;_;Ma4o#L_unzNDEB_qzO@J zBE5Hz8amP;gyikux%Zy)@ZRzMKE{ASvesUEueIiy^PAr{cc`wm+L_a=rzt2X&Zyr~ zzDq%I_7Mfev7e_Xfp65}#KkEnPSiQ+8+#dRX@YItU4^Xe+->ZId|mGY?GzMp5a0XO zwlI4yP8)lulbbx(N+p(y)5%Vr%Sb{?SnK{xdq<~RexCMve%kuBelS}ZJ1&UAX*pjo zFo3JQmo=xatBV^P>?_Z8FfJJQpZqn5i}Rq17fhbZSWB1lrn{#-r-YD%kT93RX-+v$ zI|uMxW!1kf20qDiIeK~B2ZKO9K0ZP|VnXhoP>_g>j0{Lv6eKEo9q4f#{=m)4+V{E} z{0e!9-(x7-!)-mC?t3}8yK$1ow6<|ac*%2d0qvZB4Q^-q@3HSAJY5b(wzCD-#`w;eT|#@96I34tI3_FPHqg`Ot;-zE1y{ z^FMAwZaLK5%gN!tbSJkQ>JH37OY48n!qxR36M=iFcmoUf*Czbqf&Mjbxc-Ct_Mp4= zaCd~Kt-XpjuzFVx77n-@_@<}5wU@mz@GH+HDl95?U0CwEh^W4(Fj!m^EGj7=EGjJg z@6KB8c1{it{?u7Q1S}#0bO!&uH(*Y7)?U{CFa7_$;9zp^-wy?t^8b9I|6Fs^-NoG# zcsO7VVh0cVpC*Q5l8r`hCh%`!5g|GD_!_Iki+1n%*BO!DS})m^Qj_C`*2UXFho?msP> z_HIye)4zr~Xd&;C3xa$s4BVW6ef@oxgC^tuv;h|h3xoc4E0e=*d(ql**yyn$V;-JtSZzSr&S9jp;9UR(;QF7DP|PHs?LcPBS5MNd!b z2XY|tNp*4hYpjD${~AmV^p88q9T+nBmJ{5|-SffUZmwtV@z0wd9C%L712YC&+mdH4 z&voC^-40=EZ+Ec7z%+ih!rdLbe5^g~6`_Cy%X29@I5+`o^neraB~DN`drwYLPGC;~ zNA-^}eH`t95&vmOf45f9->37h$CCpcn!xYb|IKd!*Zuwu@P~k71^wHz0w4bEo9*2I zEA|9DZ~tO_8wJIYhfaV!9Rv0&P?%Z!YSvAU;4oNdw~#Jjm8 z?@%TsNMXAPzEx7OJZAPee1)s9uU20SO$1cl+chQj3(MnJBx0MZM*J1F{o79<4x|oCdbaw& zk-6^52l;O*85dFV4`X~fq?%0o6r}sc7eD5zc>fGIHptQafsq*F@-cT+`g7_Hy;G(I zZ>_Vti^lw;RxX$ESRqbS`nO*pwobdt7C}2{zyH_+A}H1UTPAP{iZCbg?~y|LB2fwo zP6~BpMSb7o#S#BEcH0(XyDQs1+9Q>Cg%LO^Ml~(mzA0`A(R&UQqRNELmW`(Wqx~+A(|Z;t2XT3^z?J;` zCK>D)(IY5xzB^lE`<7T@_-Fy{8m6Kmr!{+?RRZ~I=E~87ApigKpD#iiekfo9zOBgU z5d#_O!*dzd4Y_fIqD&#bXYAf%-9zmU&5qOZQBbrM+(G&y&Ou^5uee3ySq^oh7=A(? z#y5y&FDd6rzS{oh@4qO-k@EAnBZvClr@wsk1jWxmRtDr*>KlmfZJAa$TkZJrTg!>e z7Y_CQ$#~=VX^Jl;h4DLL96_us)u$6*N6Nd-Y<=K+^{4JUs^soHQqC>WocV}_ceA`_oA91Wm=o{_8Bv(*R)p04&Rtk`Cue5w|%(&j?DeQ zjam&W{ggL&C}sxsQD-W7|CTLmDH8?W{1u6B;=X_&uuj~|Hf^muyhWlnCz-cgL#O-Je2=@cMZ13O=9q6ZE9h}IVF`4 z#lu_S#;S}4P^|1O_U*u|SQU*KiH1-Ya_c^!H6CeEei!*1lNun&JD$9EyQpyY%UpxP zx`;YgyZCXff)woagn}YkM+E}+@e_w8T&8&b(NT)~_FEr`GTys-%8!H9R;tq!s#X+j zA7f>g@AcMeaPil_sj~=L){!yJpyb@>obr*``ch~Ldd;?!pzOyGK zlq$Q4%r6ki(?HV9zeisBqw!Fxkr&rDZ9*r8ds!39UP@#+ZvFN?VQSx!&I_3A;h38#2;VyJV+`Ed`W$x%_9fx zG@B5qbTZX@Smf{?+}|WmO?c340X3k(8BC3S6mncm=krESPiVGJRw7fhtno#aXjixV z&zXhgLEr~MP&`s8FQm*laNal2b1P5rd@A#HKtB1CS;y&Wwo{ptEdhe0DVv#rYdLc~bMm${nyh#uV#hscg zd#2MNk&}FD<4}A6*MxZ9_1It^tmaW|118F+-!_IP7Q)hhNM$=)H^YWP!Ffm@Vm65M zV{2yq6HWf(jChyx{7N+B#O|Lz_eaR4`QkfCt69jyA+0TdFknFxuYc085>U4go<6UW zGyllr&oBm-G7(12e z2N{3K(K+gzi7}9H^Yb2;nEp}g!)iNkJ9><%A!W>@+;_{$+!9>Gy)WX(`ow`r(RJqH zpIlJB2$wF!7wQ(vi8hxVC%gMc#Iw421fEBY>>Yb*Gsh8r%eDJ!GTb9`gwQ^})`?QS zQ#lg=YTS2jj#9Gr}jOLP8|Qxn8c$5V+!LkxtO~n3RuX zk|=YqgOOqvjP_3^2@3;E@|V&}Qe}Lk0^Gx44DrG;LS(#9b{XlKExP&;!_MLJA*+kH zSU)(uE#dP?NQQRuSo_8UmCnm;qjPpOjdy76XGE@WplTB_+A1#PrdG+xse7Zsf}>K) z0V!}DNgqiLx&2wFf?(BoakeKjMvCjSj>KfDKRD#nV+X786>tW-r^GAq1Cck*UGndc zr`LnKOY!)&lm!n+D`2Ziwnkevr$P7~F}7DxFQ2_`bnV%wCc?di_WZp4TfG>%F(G+6 zE!Z+ikxd@@<0tD=v5}C9@}S)%TwB0gQzyrxnLfplkfslPWSZljKMw`SVXy4<5+gE< zMhKZP4wWJ%r$EG|u%w;n6V~G#JA2PQ_DY(zEJ2LTEb&FKOpou9AkA?sSDZOA@@^O(=IefiTUG_7G`?_-aOuC(H8Eh4H#X7S3?iI$lSS11q1Bj2;+fL@wN82jY1k#Od! z%FBMSeejFX(~iE2Q~OqC*}WY45ZNlsiwVta;Da9DmB0fu5f7geo( z5{pJ|*#d{VNHJ@@l)Q!8hmSXfE!oAnG5DL1E|wCUl)2^ZPqhy5LK!)Pd3=}3f=$@0 zoLyWAt$;bV$#@Lxcp4L~y$lDbbcgZu&0o=7rOo2m4ySqcl7FIB21_}ArM(%PwJI{p zP@gr=1D#nZ=;guoy}1{(xDYi-s;KrGPho0R*m|g*2 zx;rb6LWn<+sAwVDXZ6!jvVQ)QW$yvDB+%8*6daCtT~KW-od)^I@}%^Az>d zN!}Gws#4*a9;U*5_=xOMFE0@Mi9wYmMKLBrnkYyC=tFZZlIQa5JpzkQjSjX|X7QqE zPMXtsR+@UW(0N|44TIN4IeuL*j$cntjC#y~FRt2ocyBzpvfpiqur3x2+3@%1p1Vc& zXy#`7BEKU(@#7swqTD}ECHd1&a?Ey9t;|C@fad0*tU=z#+S7QK_sn`i=Sp)Do-w*x^s&R)JV$3tK}2RRj`Nf|+cr@e1{vzN+)K#RmM2Jcay*VQ zrEIZ!R`vYwGlG1{ktM0oZ8h^2X${KyXe$pXbWzU3*KhfY&Pl}`yvNC+-uz`3_iAL| z(u9>PZtC=vA6~m%VLQzF66GoR4|)3X*^oSUvh-+quf*MmE$iYKYsgZdG~ftMoEqFU z&|NL96q&WW(rd?}Z;;`@NHk10MW%^301L{{&~dU?2!-scgQiM@f&tL=Gtq*wg+2NY zD4O#*;PLN^^=l9k&OjnJo}*NiADaedc>kImA(PCtx$za^e^Sv^$$I&N#i8TAZjd7F`%)zHV9P+W8utC#Awd*+K) z#Opsh4}YDI_Ve?HFUgy+2}C;>iS5IuHy_s#ce;24(DN0gu`k55dm%l$47viC2@WZK z;zb7e`8UknA#g4(g`iT>|g9PERzX6umSfUSzttHPJS;V7zaW5mG;Bc0{XJp{KUI zL8im*NU{Hm>K#3`+NcqZ6~I4KjfH|&MKY~+yjm$65g%#hCv`cV-hNS!(l&n)m>dyp z6>F~x;48Or*pKPZ718=`)v5+Ao5`~E)amq0;`CZwCP*DglSuh?7r>mWe*jotsOf+N z{--KAe`a%JWih8X^W(MO?l0GEV%t-jT{RUu8#2K9)a4fBi+C^>{Vr?dM_qJHYdRCa zh1jhYl}21^?1bhfK6&dzNC>cUW%cDLMQIUa?t^P=+qvgo0S>qp5wDd3SNwRM--*Wg zV^e19$#+I;mKRQ^uWc-TD`nDn?fznX)e-+8QoC}KS_iVaJLV!$`Y%Yfu;E*aKD6>b zPaK@kE8j`-WHaX!@xNpT0wDUXRGh%(NrTN#9w)=!ZPl>BnpR+vlJNl)4^FIRT9NeC zmD;^l#i-=P7Etq@61pVm_*^6=&}|j>WiB#QF{NU3f9|xS4}&<>jXk%M6Ur(T*0T(G z?+h`Ub@&ZJQq6~76NS*l;p~~#ncz&0{bppW<*CFoO6xgj0F99>X&)a7whzq?me+64 zbzh9*5s;f!($0Rh-5xeTB_iA3{9LHN)Lg&%bSZCh+b!QJh`TcAT1}sT|F|`hkRTZ7 z;LckJmE$H}AW7rWI=Bt>TWTZPB#9TLM=Y}jA{A5cS$g{m3@j0f$4Di#yb7na+;BGS z1b*0=Z(7>G z@}7exS_~eJ%+$wJTSi`smYL%V1Fuwj5xYUTdFIBizXG85?Cn3KZI%Z#Ra<6NEowlz z>-*26j^`O~*V+1fUd#gk9O-;df=B~=$$P!6Hy%V(tn6}Gyi8oAX7OJ@IZK#q6{{2G z`sBMPxGa&8eY zaGjz>NRu+5;MiQ=L&}C_-vJnZNh6TnS2kP{i~?JY8e0Xev~JaxUtYDbbT<$^qp%+a z{T;OJ2J})wb{KRKbF5ieVaVjlAi$cNSm}a!a?o7b`+HoSfPXPk+-J=ao8Z0``G|}l>Hmfxzvx+hWjmY)+`mb7*5)t( zL^cZ{F?R3THvCBAv86gKizF8M<747v7AKxQYYqZ6RHv6u-}F6 zhsW>eC5P~oqnZ+(;(x)*O3FW(hZ_sosA1E$C)&ihG(jUf za8JLnsfo9-BtF3lq_-g#$OKWJn-m-JbH(S4xBaRfLfRLr^asw|kcb-vV!3iMYi404 z)*HjKFT)G0s*R%*@j`j)0xFHh?8N4_thym&e>*u^K}Go>nrB*_dX3%-M51W&%eO9> zix#?`KLDNpBQYmyrER29q5du}rb2r8UW)fZ>_QF`5<4w$HR8j&z9IJd_f1FELgpB)GIw;Ogk4 z0LU-cyBcy#-zElv;xJu$MSInix_tZFwr&08)JukwsFa|ME{+eqsxOt%yXVPy5D?R` z;cOc|hk4TWXfhy?AX6Du5f_b#7h-(tU()zZ{8vl2tkxOeY}73^86gDABO z0W<>mLgiXDbZf!mFsoyTN75Y6w%pio$L_M22e$lBE%V4zfZN!3&RkbK&(7gr-y7uT z58H&M22HG=1L!cYGmAKq#rKDRZ_S}lLy_u3ww;{c4srLdApi7ODMxZDWJf2MlaPM^ zT35s+$FS9Yt9q?6<=87vf=F?9%eMf2h5dkE z*}xB`Z{Ho2D%)$-#si(&h3sX-oHQ0 zV#bEFf!Xdpf@flPROW#5xPW%6wg0Krzdm%>MD9nDDS$0!AjsR@-xWIpsa(Yke~Sr( zhpQdn)|igVXk%DuQVW^htKJd8<<7)Go~LN|?CJqQe#=IQBhWebFT=*eh1if`jy{a* zy_Wwo&adVl#Q90vQ6M{uOakb*3SfIFZ8cq+)rX|#30u?YVkGD3&H;dd3eHe;3}O-Y z{}V_2JM=6%klCL01GeYYkCL^RA*(eABOr1xbTo=I6fO0(BFzA15+$2rD8@uhPR+VA z6Qdz{+#0At%=>Uu!b(nya+>=2H*&3543iBZL5hn~>z#IEJz6`N7N^Pjn1}l9%X;)2 z-E5XYdk5Bx^mSmBG~w*uK7wV^E?bt(-a&haXcILum>GJt%3z@U8tEYB`- zIJqgaCa-vXBPr!O09YS_{tZ}P9RSu^ASt_pi)kroS{ZS25jqokd>!A%70aL_FmH6D ztFDcE10WGF8htnRC(S<+)d@1AWz5~#q`=S(!yA=3Xu!KiNK?H;0gkW3oTei4wGl(% z>-nii_>EyQYJEpWt+p-o^+Vc_t#-9^rpFG!x;S@@nFSZXzDL$g4p}!vn*cfN2$MOY zN`Pbe`Zdi5m8-Mj4}jK{2-!C!t9NZ-`&9tIj+XYAH{$ULhgb*!E^n?P6Pr?-y82>A zk1&}Wtr}aVBSBB1MV`g^p^o4PNmJcwDU&wsUy!b~>U2->LpS3TeZm!i(B3$=yN98V zbr+juuG-mxrV@W#qYWjjN0?DESTh`E%7-b)yphRYx(`?T+`zur-r3Zh z4q-up4i{Y%_)XEL0cQzf7eEfHuB5ZcDD>0cVD9@09%i7#85hIEYzMDXlR^0RkkN1%p**Osipe)K}ne3 zFm({?u{xY>Wo~6*`r7h1tA;zR_@A*zzAUh^55La>+6vQz{bcjo1(fw$eL3%jrcraj zIOJV@Xv4)e#9#}AOsqfht}L&5zEcDuG?7Up$B!EWbkeUMxMG7{v4O&g=*HkwX?yHcwvZ19s`r2Iygi0Qzg8tmRgzzyVHW z0=UeJ2=jl`8_@^W@{@0j_!9DhqUfCT>Z+viZkfm zzjXUw5qzxZmiq~DixZnLbZbZ~=kCBGfMS)C^}b}N;)1ZjI|6Ffbw%b;k*$c7{Q%oo zkZd9a#qU}G*uJYy3Vzt?*58$_wcDd2hi37xiu34+hfMjurHwZ6qY?uPbvJ!3qEbgl zT|B3-h~clfkw)I1q{d3C{pPyn_}@oF0h%lbX-dlx%u|@TS(q6OQPJ0;Tb-WJq1BpK zUZO-DM;jS9Fz744EbAJBh*Op*uGtE`u)OH}l1xX%F38t@nrZXRp{ zvzXWcd>#K6e0BPlDwcKX55B`U74RKjsM}uGqMW?qEh|=`fzH*{q+cnJi;Q6qZm#q@ zC*iFnLwWT`6AMfHy^CrdLNjbti~WB?uK*LpvkGM;rH7;cLa)~Q>knc=6#?f#4B~B^ z&m^U;cVvb*vOcQdCTvi@rSrnBti-OOQY=4Y&p+m*fzE7U^Nle9MHt5VWG}J#;-Jk0 zAO)Vzi=4g=JbcN^eRI0QQqn^l6~Hch{xC(VL|M2upY&FxJl6h&nVucH&M;;oXg~_Z zurvF7(9Yb9Ul527Dj0FjweP*Sec_jVFA&_tL*?@@^$I^VkLqFxvshFuife)#-9sQK ztWRT(*%g_51F1FMEBV*Yng!P>V|CGF9}WX!H5(9&nz9K z?e3ae4fTg_zOsThEBIJ~-fMi*!cFQVFQuI2=2SC8!n{(S?Jf6yHt;v#@l!A;8_&;TA~#C$!`j=r0edl4M8 z0uj7$8^XoaL$>p}l&w}&z7S|%{Q_dJoX@?#d}Bh!AYL$Ni;*pm!15R6T0JQKOVf=W zIVxA*fYv5_gnp!O?o0>HJ3@Vj#mlyRW3MsLXd{8T#>UCPZPn~_-5SgQVJw$8xLj;T znpupECaA)pMc4i(ZcU{J9C_L16lo|mQepkA`4;#VsQ%5b{>D8kBYqt@G^U~clHhzX z$DnZ~p%PF^H4+T!rN%pT4`D#QiBxt|^RRSvm=2pbJ-mg0#MwXzE z1DkHMo9i0ex|~HH<9my6O@S4mz^cUs?$NaKS+7Oq8w(FE_b&vp_Zdm`zXFhR?qmD` z>k6#ii~Qg)dXA?&rO#{81Dk+JSLBj$YgI|;oKym*wDfXBUL+|17P#w*YYkY{__y@< zCF%av73M?k+t(Uk9Udl)0s6uBpMZWqCZ`4hpW|>$(fhvV8As<=*nXH+jySuKzLEoe zN>L)2Z5@)K#qJD*uLNvl7j9ighUrOoEPEJ=Q^~t;ZR+UpQRbUdjm-Eh_@SCMrED0w z8_+?UV*9DTle1%+B95G`+4NMM%mbm+AERSCJUqA8ow~mt=#@W8`q*qSw%XvRv{rYE zieFP$)2e_V6})Y`_^B39aK<0SL4R@yl2ieis=9GNRp|;E+$NWF>`~WsMu*OJznL8H zhT*Qj1ei!4x}277fj(#)=txac}rPE<%6F`aqvlI+F+hLnRYh1vAIvdvCq(rN?Gqk94n54T^PJ{P(3zp%~KN1 zd;<%OiKZ;<(HZB=mWq=|_-ws%B=5?Su9yE);;iH%?}Q!^I|h^nVFQ@$s?UCmCyQYf zo+U&yrW`)}^+NB35vWy&b(3x%)4?1qh!cmWR z<;-3>IVJoy02T?}%q}l|Vm-bLK;A_oZ`LGt+4cUL9P}}_{9x$9jfu96?Zlvz$Q$dZ z>7=!yGlwiJUx9q6%NOnU;lpd0v@yTF#8hf)whDf3dGnL4;ZpP9j*TsB(nqpa2$Gx+ z`mwy4N!}H1i|vil*nTl~4rExD_y$1KdP+eFCRzHAf4sHb{I)pp1SW3bMO>XWP0xz$ z(yOz{GtKRDuHzG=JclI2;vx5WBcdxy!aVTOzfMZ|?)7AQVLpxi4y=ut5xukO( z_wvRz?;Tt}b2rkp0s#EX0B7O#20$D9^E{b2E5npG0kI-q31vl}B#B*{uhUDdr1xfH z$%$0ofQoKXwK1*XVd4DCeIWC`4=;PUBUXve?hJ#LQOn7|C@Rfq;gf)<|5ROFr`w27S-;9RF08sx##Gd6X9%q~sCr z0>}qrexquwo>u@o;SC$aR(mb4A}b61JhUhQZwKc41Fm8gC>!OapkNkYdoZ)oq>378 z7xSS~;imbfG`Cf0xx1YSJ@jQ_1ukt?6wjNc`x> zw}7nBVXU8wsmHK}C-#pmpFm>_dyLiHWVPayx~A)u6U#hNWK zHZ8$Z-#|b1``uWS&%1Yts`Z2Wnldbe(q1MLS&#gI{(xLS!SsD=oOJY-@sLb6k{rp=AQ4=9Ah zI+Mm_i7Uc_L8vT4HGsl?*C5p^L|ViD=xmsfp5FoNjW4ms?7DtQVr^0(_EHYB0H%;< z0R^Zpxz4$m!o~@x)IpG`k;6^O`E=C-$WK2a0U{0Y-`fwbE3adrH~caG_(tuINB0BM z9BhX$TCe(WjL-?s@>~pt|E^1TrPqAN^hhdlYwD6%U3O!rcivrRO)W!Pm}|*Mlnt#% zy`#O&J85}{)d+IuORaLAbFZP{VC%^H>yAj8!KND$R5!%NKV*gIZ9d52p-!A%(K&ht ziNpgHBB6>!C!0sL)0`qFvqt(&k$j(4ai{A#t!nqNFaBEfN9OD2S7{kA0o1f<7gP#V6^6hEa2FXcPbP}ie z>6!^DgX`zyZF~0X?oMj~%Z57j?H7C~DQ9RG_v4bgF(-KOaG}E&Y6`N^N#_FzD`OBP z7aic9d!k2HKXRnJN#6HyZVo>n^PNh)iN3oN16D&$E~zbo$c%V7fdLAAamKki6vnyk zd1^xVIYq5xDuum?wq-ojitqp~<)#?N zC6|ppp2%7XDsUBocsRS3+P-pto-PSK>Ci*UNDh&f;1OaBzvKFjRZGh-C8SIHLN?qc zvcoj+ojCm07v=1`y(Jp)W_?q2R`9?abbivK85`X>fME&*Ub#XvDml_cWL$GvYo70n ze$VahL>#k2mdz!LCk^2ehmtt1U(k>|^=-%iF-vl@k0{SHO~RiPgP%MNDC{*U-eRrt zV;?xhw;!uj(H^!jLlrXMcvhGbOcZt5EUF|pMO+*8?h_aj7DLWLC>3`iiNv?ylwPYm zA*-GAyv^x06KLH@^xQhGt*-GW9xBK$6e%wjjxtnsE{Pqi@k0QdF*r_ zoEx!k%2&(`=;NEx9Wj>Syw3J!{0z0s5*{wDt{?5Fr?XpU@EMUyS`}qr1jpnw!WB+X0lW=%tDd%QZr&HX$Lgd}+sSbN1^%R{DJIg`t+MVnn`i$~6}z*q}PS zE^oC&^Jl_RgU)r=CF^uCnuu4?!-eNBM2g%Ttsd>dfa#BW6dH%*^mvNPn81<-Yky4Y z7=AOf&8An8ayp(kAFk-n;^@v$%oH3Zz3J}zk*u@RE4(!;kb z&T0ljE&+wx#(eA&^_pjZGuZe+m(V*9s8(HZHxKD#yEHM~OwCeC37+RTor6APRKxGc z=_Q_-0hv(<-STF2{#^+;h9rC$A6gDH0usO?jGtroSD;E%HnL?~$VzT|D6hBG*=@Ir z#y?~OU{ur@A(M6|#CJ`5YDf6=d$JSz3m!Uf;J7VpF3@5L2_~e^n-~3in$Fdx!-vP-%{J!rMMJ1-#ty;YYf4< zon!qk)Z3?s%Ol$F%R64CGzqlSPebEU7hqK$c9vxhAKNTx1}%0rL>xPR;;))&LE_c- z1}w5Rj}(EFo?pt{Lu><5ZhUEJFNF2UxHBM=>h??kPF~)e-)Ib6xzeskyT91FtLW%lMC&C1Dd!p}OZmSue3GcP{1ZVnJ z&_sxgmN{&J;$YjK*P`<56F#MQXDNz)G)>lVSSiTbC=8^{i-nejSt&D%#{s?!`19HgD${NYs*E)33 z4^2~#nnTQjPS|R$?li_@-GWGkV>I7>$tv5;enW@c>UKi91#WhNTyrh(Yyea>BLVT$ z!AQ>bj)&7?LjFSx=C$}K1_UOf637LoyE9fZ;l$m2*6E@J8FvC_v3d6KhLs9iPyA^7 zB`4+By|k3;46)*+=@m};JdYh%kzmr0|=n?t4GQw;CeMxV$S1;d6Q@!tM2m^1Pf~d_hI^uk|1AIcRYKNEaYMbh|uY zc7j2@UZD%ncpmbEza6wVwUifn8&uA~LL*j5s?ROy02Kc#ce;0TlnRUQX?~ENDAoXY zo28B6M=NjMB+6EPA~dtiovTryB>9W{>h#%VJ+ykmcH~n!$W}s3u%KwM#2Z4on#koR z@Sn3ISaZHOq_P22m0W_do7d7~WmQFJ=I{Y8UGflOdv!Man_m+uXjQKhp(9f0m8N5x zUP*Lv@$8UZFWZnY=OJF8^}tN5EoHFL4B~~-7E0K7DbE~DD+zT5N?b$nq5jLsInAxT ztg#JIC6b?%aLFMebQdiAZ4`#X-ZLRHcJI9jI;#A>i`E3WA%J6LYLnXXBV^H+PfTeR z3XADcpRU4bMbn0dwB$ZsHXr_kBjG2bKgEG03%)gBB`a2OFWi^b5@LpNs?iA}}E>b?AKA;ek@lK~h<=wMbS-i0U2xoWgQq{5wC)c}90VTb^fCss<_7 zF5Gs1V82B=U^TQ-|=u2{mhq$lGbCWqfJ`FZf(P+x1-j##98QE8X1*emnnU@_$V zC{(;%7`bP>K#z#sCJt7Y|C^Z*eH{7ytpqn8(hM-C6DxXTg{Cz=DcVDcCO6 z1F~P=K!d$|I9w=jAjm+ZT>F>;Z>#het}!HhJ$}@3Qn*j*c%C8u*T%i&6dA9f)w#iL zy8(=|?b`Q=-ng8htn1DZS>a2yN**>E>8JOPGK<(C+yU15E z$-?jI^16H&3tMs#mK~@{pzZ zMvpON-ZIQeoCFH}w_92{5<@3vivZSZ>qVd36tk_7(jSUye;@81;AJJUtWH_3!N+A? zsDF)v%nm~&DtA^QsVuM8+|;I}J*eLHn@g}77&P^7zIxe0Qm_RT9=nLo3^4$*FIQIo z+aN;mOF?cP566#`&RsiQ1;|0}6pcxpr8?9g^-ia6!8U#1ih)&s9Mv}dUG>+;OZX?~ z@X||3(m`Y4TMRj`-?64~aiy&3BdRQhIHY_csBYfz@Ng|GyR1^!dYkTHhI zzeaEU%iV#1^I(3O*Yd;X4mkw38_E>G>pf?}Azcd_FYA*PXBNaMB)I6-KGTZ?xr_Qo2x4ikNk&3qr*+hgZlq+@j@awaay-Il*y>_m zIi|BA@x0z6I3@#+{Go+%qIj!XAW^aAn*=U;3H$a_<=Zy_OX5jK!a}khSVFJE^or_g z3IZCHz++je2GmdQ75NhEU`4cvoadpkcT+&QNgut<<)+jhkAkvFuF=U8ce`|u%VP1V zO%F~?-`34HcpO|nd?q`2w}kFOtdK~QvbT_1s8hZmYQHI3Zq+=>qlJd*2C4_Drrg;U z&68cowz=z(zwNG937LH9Ws;0X>Tq$@%RrTrdHU!=;Ekf$fY@Zhw9~*sDsx$sUqtrJ zhkwW^$*$SV9*{a|J)U3a9$REJ2)ykyL@w&Wbq>9b6e~^H@SL=cf0TLA=WvR0f4>kw z+(r#RR=0Q*-DtkngnATmVT+@Bz4q-S2rmU>JG=&nAi!Njg52HnvHsJYyXSz4iR&Ih zmHc1@utuD0mrC36>8z~!pt-Jshpb8F;;r&Rk$s&zdfZG89s1bnLeI@4(|V{Xztn9V zW2C))K|oDoI@De0LX(df3?$7~nl81UkbB*^;%tJ|@u~_Kx(i-ZH}JIluB+e2^UvR^ z%E|_^Ky$iIJqF&BGc9q9q%WjSYP3910C=CAf*|j8YiWUcN{*jbhY@y0# zF-ytFwS*!RvHK~`Z&WDE917*_)rMt?`rP|eM4!FH9O`4^l%J=Z6fM7@oLMd=sJ^7f z&!}0hFFNgcjqk}@Q&?R&tpD^f`$Go>h&rDIf1i~BzfM3b)wf1zXJBV^-mS`KlFVfw z6odQcL#N^tua=?{G=q6y=sBp+8B~vZ4Djzn@!p)akz&c-+@ki&Et);|n}bJSnO%eZ zqvoV1i9hE)=t{qJ#?*}R8;lt7#f?dqu6z#%vU6Oiq@ko}n}iFkILF&_a?>GuhxC#! zXC9MkkQBad^-m4vwm&{Hlg>38)aA_*f;rt zn6NCW)0>`%wH9k*-#jFwR>tRTVL2Y#@TsWB46dKkcsHA^;*{SBKnAUQ6wtN7%>l*0%!XNYZ3*c94(h1ABo*p3-g{8 zOMxIGzVjV1Z=I?vsn4;?i+bD-%4dCMJr?HTk~cIu>L$PTJ>IC4Ez;sjr$AijjXi~% zbNI|6CuzZnWJ71MF+)B^3HWN7}{CIuj%6)l&@T8_?Lk$ z?J5vb2p=;^+cRWNk3)j@Q4vrx$7yjCK~!KdKeFt9l6!qcT-aJz47;-pRLzxQoIRRl z`=Y>0R%YPse(Z>GW%1?xCbT4c?mESGRDKH~{+$3^c7lt!A$U1L+)45?VU8 z`9n&ljosJh{1c#vgIGE2RH{%|5ilMP@OstvQhF9eCtkqksGIbGI+rj#?8Y^Wp+QIlldu-Ar_qBl13msPa zVSxl`Z3ABA4b5&Rg{3yEEJ?@G>;r5s$M??B<FkkSvVo_v2)nN?! zedkU8cT(GE%1M*>vCTkI01`W9vRn?^UfLXpe;}Tg(BT+QK~?LhD-Fz;E#!Lv-bgl((KRk<)?(n*NLD>MU z`JDRG8?Cez;*baTgoALycTx zEytIU=m!Mj6W=ao)f{x5$*3WRqdTTDtJpb?EcWNT1&4yx#D1|_=9GH6Px#c(Av zq&sJ2^Ik7w+qsjK9LY4>1tRFEJS4kM*_u&)U~f){{c+PE*CrKZn^!4m$3hmEi^GH# zhCHg?NOuuEst6_uoE*`RoN1kmk6&$D0+_=nBe!4#^sdqCcd-+aQxEVOvE$3n&!S>I zy~<93E#Uf`QdJ#PF!XJcu3tq&X(tzBAyz7#(LVhY^lRT)m=a`sBXA!*Z3ms(A2+m75b8+~?N*Z79O z4W}afR za6|5eJCyeX;J$<|)Szyf`j&m*%O1MfLWcI56YZYzhGM~Av=Mum3a2>b#z$Q&?Krem zPhw}xMU+^i#Nug-uT=P(eDYhovhcA-)Nvq8J6^HLpxwFA(11y~>ZobKV?!7^_bVS3 zxl=OXspTa}hsF7Uj(i%hEE}E|48ZozOjMmq+gtQ4Ceinykc2M2uE}^)N_nD3pT+3H z>VMhS-y6P)dajICI<>l1rB9%`D1`4pE&PJBBJ-0gyej%2n-G}ms80c)RWCKfju)^m zx(2;WSiM?rd)8iX?jb+rbz2>&B7)PAhqnf7OLHd5Jdea=E}-7zBiX68exP)#dX1mD zseO~@xtoeZolYA)2g|b}-8~6zduhdf&W9v%B<>ae%})d8UwyxHZd*I-hEASC&V$6{ zQC1(+8@u3b|M1A=1S$D7kwF+KMqfNHW z6F+*vyV0*jI|dg+#rlg)egVNm-D)G=mv%k9vG7E4PU@>;_gI{gFAt1Tt~FW)tPdo` zF175WM}0+I?V3N4X|<<|ytc7%^ap*>Sq13LcDz4*=fCOV$p{0n7WsgW$7mP&uAfb~rPg~Y)3;RFgJed)%@0eXefRDNW zuR+Jna~4O8I~YndA!_-b$$TM)2H8Y-6-dO)^)q|o8iiS zD%0moFgqx;$yhu7a{94r2KEo0m$0|U(3uA3%189FmnB<95IS^5`%e+?z)OlU_ENS> zEFa(*wLz(!%J&OTUjlF?nnu_7cB;HFdsGnzL7?)(G<|XTO-c2bWjBw{@S+>6V-ZsBE>+2WBxq=H$G$-P zUP^lxzgE@dWOoL(X}*;m>)f7>W3VGG2t&q6wl=Nm+#|CQ16gk}$L$^ny^Z2e=^}`> zad0{BDNeexf_A8#MDcav>_KOB?Flr}LIu<+&G(LmU7S}&lG9eP?>w9DME50 z&A2GVUiV#9^gt~4_1W%zRt)K8tpF!Kw4h}DZt3z+Dzhu_` zudW(s*g5^;6wqOL$=6w$Es#B0j3G+sp)-Z)HG3iR2O~as>vi6c*^Mgp-0wv?mlj?3 zof9K`FeP6G_T-k02{INW!JF+@!co&}mubuSiBt2qo|im59kZdU(5h}@_s52hELo7P zPtcodmqn6PbGEhH+yfqlESFnK13v9qsM&iD=7 z>+FufEiFe_WnV(R6*_xUrJLdfzm~_94Qj{+qCsp)NlUd7*m9S}w<8+Q``r8nqhB;! z;SSc~X7dqE(prAe;#2;89kj$8uzRPQY6uG2t_*iA30$b3TN+;~o$U(O`1N2Qvh$)@ zY|gpVYEn(kQtSUA>@CBh-o8K30g+Zfy2}Gdmvl=g-AI>ocjri#2+}ZwGy_OC(#_Bf zLnAE=9W!^%?>_hC|J*n8eBaO7dwpuH4L><`#9r!^8&@TG=QHz+D9@wh&L-FV!Jzs= zJyeAl9daCUpsASaAe$Sq`8dtIJ<`KP>eq&1jiZU?+WEb*RauOh$BjIMS2z^&x_gW) zwQ^#4nXEzVF(ac)gfuf#UnA2et+~cRBP+6?YV2<+F=2UT>$)FL8TxNCZ@FYr(QH8p zBK|De)0?#JMPK-_s_$X)!OM{IwLLwAR91Y*(Fz~vp8CKjtdFeWwT$0BtmF3D7nha3 z>_3_}<^?G8-}{{hitODqNmAzqaI}1gQQ%#&b-+bws-{cVB2eGZh!*cQ#EO3@s3KPK zdOV2Mr)9y1AMUw_&2n*d?7laPJna4R*kvyWDpuWy6KM3s(Ok*8C#v{$u|9Xg%PT1f zerL7D%aB(AYp>0wY!S7ZM>CzK&7COw+LRvm!#M08H2I8CUbfmd5ab_qmfQb6WcHp* zxNJr&L8;))cJ@U!HTxo;sCz^65Mj3@A(AT18~j^;_RlnyA5OMt;SQ<@ zF->B(yyfBq=RBa1tEf8UI)E?f{xWG0S&zaltKkx}8o{n1R518u!mk%l(TuWFtXCMzNJXL80uOo@Dx2G)l$ zqG~mLA)5z!zy%3)n)~{T(_HD&cK)j(uicReu3NtBJkz~PD{^9>7deHf4rgec^^ixp z6pZ~j;{d~@7Ykurl;G!4IU8b}SK3XTbR*e+GH8a68Jo!woiVDjdMVPQG?>3v{t*yO zm0p>zjXc$j#T8I*TozP2Zc!#%3kxP)DPbS%@NIi%BA*)EMJSsKp8A_4pBdjLwUu=^ zTaoVhW8;Fyjyr=0rGSB?&)!yZpdGn zO!|JkZ~s<@+nmw>==by<#J}7{0CoQPhX>p9d_4lVuyJc1Jd6c!olN-tet5~O&Jmo3Xwn|c#r;;?M?B?znxg$2AVwLI)iRtF}Tptgs0L@*L zqDmQ|gJJ=D6$6^5FWEGTV89hv*P#hU=JKmq&&yN+M4mkmR&hIEyQHj6V!9ciF5>W zrikn27*5_Y+qMic>rI+0(aLFbbITis^5R>On+-_`40CTR_unnx00UiiF%kXO2(8{PXU9SVV%?dGP zW!$MvvxD+2vvcNv=lSLcbJ(+D`F;m!bt=3>)#d&+3$J?*D4NX$-^ragHWZ==U6B5> z)#iHN+BIlhq(0t(@&<_ge^<;`{E)%7sKheSGh;E5HhpRl?W9s(OSVxqoDx@y;*w7q zfYX1$g>l|L2xk|co#t3Er9?SXSl*a@Pk_1c#kSaKB7*mY3%x#+Tz9IdPXSam*~KHw-|se)wyNaryFd8I)oE8t zvsy4P>7vc(d{Pj>jaTB;L$C1UM}0M|;t|#PA}YI?-NbGAuZ&uywDQtN#x>a`k-HO| zbd9qZ)ub>bjx{=sW$+i*!$y}tF*~1C5-Vao?r+6Xb?J-}WS4gfac&)Mr-_v3=W9D& z!SmC>ME9qm=mTfMoquX7Ni$q9|a};R$RN>sT7s50MG!F zU5AYi4@0xC-ot;;wWNr z8B+4_7vM{3a?$3)1vb8ubLu#kUml;(AzCKH2r!fsUxGgT^jOdt%c{r8uRr=T8Wvq1 zFT#PTESnbX*otIBA>Y|vs9P|+edOfcJL?|o1(|%6l4=3ja*^)p0*{R$k zM0rtR!o0hw7!q`EjMpg~;(T7gfvqseC^Q84+a$P8%fg=3>`Z#MmQvn+7rRgo834mA z+l>Rw*>*LSCN?R3?xfT?y>}y96M2R`sy|Tt|?72IxtvxFIKrw-38Wtooz!Fd~ihijPBWwQqci@)c z`T;PhGr#U4L_$w5Tx5=lz51nGN!zm7Z9cXi3ScaKvblOKq`13n%HfaoE`~3VhE zccRH6Y!l}z=36*iFM0FiD)+9F7vY#Miv?%v={P z|8+6R1ZI9jWBq#PFTmxRWxSiyeiKuKQYP$m7WSx?8?vYN7`)TXSQwE)Gp-+C!@q)P z?F6rO|2Q~Av-+qHJ@1GTl6S8e>~rqga@V7WfKb(Kpu+NUhlumF zgI*U@s3xIVARwCo0vesYnD-xP@IQMkyC&4$LL^pqQ@yat)%{PP?e%HHc6a-)Jvg_@ zo7-XFji>;6#pA%~;FsgMprj36HgIQ{Az3_%O?-W>DmGJo=yv=_aiUP8_Q`--cgR^E zn+*h7J0Aui{}}nYDEo0K;B3U#6ExD{I2DXCh7qUTaA{NN@`z({WMoB{swaQhw~5@ZA0hcI9GRvOIaJPS=0 zVAG7fm#&kd4$+MRS^c%MqX>DUhsf((KUp-ZRv;~XPpNlNTG%(yBLbfT5b?30JD@gH zE=VR^kQUu+o5K43)Ue4ZF?Tud3n?)n=xI*j7!ELkFk--q>g_JpE7;SY6Jr9~Wbu@L zQb@J0{iD^R@|$22dS|x~jvQt+LMp~pYEJKJBfn}`R^y^XZWE{2aT@xn11ZR3-DIn- zfu}|M%#cB^sw$q!q3IXnWabjDo3nI8TM+aG^bQB7(joh`)sJ*hI$?l(^G)sJI3e(A zflp0K<1KUNLXEd<|4(H}0~4>Jtpt~=g|=r$*l&mBw~mdtAKC6AKiXubGex*3)Y8c* zQ}B}~^fg9YbD{2yi~<^J2-rFNOB(AmcW+`Zr#$r)vjv+eFk%!vu+_=Y$ zhyfM~sh`2&KTLf6y@Y4{&IWgW?Od+VS+iIRm7-PS zKS}Y3W*>}rWtW<&kGimdADF2aiW>cv@UmQVWZV7n)_Tl?Ke1RkvYvyEb37>2Y0rXa zj8A_)l#lo4doAm80Nw8cw1@KN4=O~!4zro76B~$&=KH?^%61ek%JM+TzhWVUjjc)1 z<4+zRjIk-fv<9C==Dpf$fv*L`YH?i#i6AI9FR>kWbCA4=J@>P6r`k!Gr{6;h#@8w0TvwI43(;8$P~ z@f+em=WV^=0mWCuBEna7erbWMNSvvgJmAw3zdvd@tR8=eT7fDROdeJ}xgo9b1vwtE z%L-un#sL(qQ*Gy{W^WHozjJxWg%6Ub2uRfe>QFxp#gFWxyml7z5bX@QHfVf(&rBkl?99%A z9$dLYAKk&ACO!FFeg;$8lR7nX8*$aXx>EFvfQ9=JJ$AkX<&SEazN3rUAOHGNopZ=~ z=M&^?IlD7rqsMW}7RLr%&}Z@4n|8n!Ux>&qAm}uI*~PtK4x3^O=XB7bnY=-iWA;dv z$v%QL8ue5#a3J=w!8HXOFMQ>RTzBUNzw&pmGpGOKy(*3WwTofKFPY5-yfAu)TiWA@ zM4!zQF;cWIGBomzbUu6n{8+E>;AE@2NJ(6O1@0tfn9uQvk1n$lLu4bhYC6%!!p8gj zw&1eZjAOFY5~W-z9lJ^6m*BG-ZuH`Z#nQ2SG0wAt7hOYoYfx1wX`L=8DdvG2w(Oi|+^#mKdgW?qqe!{bkdn)hQxPee1 zMcui!-pQ(vBVkBHDXnZ`#Q@~UK}mh@(xw%4R0_%Psgm8Vw{3_M+=&x-3yvg{20(j) zcVF)a(X3HFdk}~4iq1xhxY#$41h0{uXIEJA=xOXi26vwEtd{S}>)di;OvYZS>xko2 zkP-)VyX{wF@~eR+XGZ2Py~3qkWk+w$MWMJ*w~Jg8J~~Zobu=&wbFuq6HUM1ele@NT z`m#(VSAGkdA)Ca0|6^Z*hbIXn_{-_s9y5Rrac8;^LvJnTD|09P)NCBvi~R^NpAYJjvlloz93Si zLp6>lfAkJt%DKmxpJ%~kcW?Zk;|XR^r~B5-Gp!Gcngx#8`Cx6j>P$&4ZtSGym645? z`4leyV^}Ex_+|taKWk9Ws||#1H+j{;N%HD|uQBGa?D0YRA9c0lMn-!7`>c%9Mjmwb2P@)$`Yx z2k~2f?t_!bFJe#Wz)moPH=}}hVkgOGmnlOZjy7CigyM;odYs47rw*7$WpV37GkE#s zwa$}%jo{>$xLH7|%{GJ=2OKV7?ZppA3(K{TLP9u4d@p##!b5UEw{vsKKSfZ;%*A{B zXle(1LLQ=Y6c!Yt`7$qnqUUbrMlqF0)xqm$>)poS&E)f&LMg%qt*p?{9-LDmJ8VL9 zLru;fVE%@h(;x?F&ij?9J$CD?|vOk1oUs`Z2+NQ`1eBLUT^ z%h)d&TF%{$4h7f`bmBrSzvZ^(vgl{Be$=ykr()8+&I~8fHztbbhY&|oHON?k9YQZ9 zk06W>g zY}w%M`qA`y0lEV1gy9J~O9VLW!#OILqnEF@FFlCYR3%G%gkg{WMLxgYz4;%IgB>X$ z#R@&Cq<+xpnP$N0I2*j_;t7Er8Zraq@klF9fo`mB+;wK|L3VKb>yKP3u%$){O;BI5 zzb2KW4i!PQV$ea*6y?x+D(pb&So(h5&4$fiMZnCTutGC3Tb^3o=Pk+?N~oJiBsR&< zS6yr7ZTH_Q?Ie|q{MCqjkwMHy6kQ&e)9SW1(f_^0mvXkO|EOt6eUk1K@KA^7$O)Z!rtmFpP9|G^OGkMJ7%uBokf3sK{1SH;VigFt7DS!&!^0FKj~I9 z3h0IxkW1o5Y?VJG=D>#(dOLT|mcEMPQ0b&A`{`Mcy54;}j1_8j6KdU^-QH_BBR%!m zZy?AGHg15Y=peH!RI-Cb3Y><+NhQ22>*`ZPj^WxU)C8n{Vu~@nofc$lE(KQ2L#h2c z4SxGnJvc!^x_k6^&+%B}3*kheO*LmHYZC1vql4-mDLlD$g<@(vfL^Qul-?#M2 zIloV49V>gF>{WA!J&%)70Q zk#MAzK%7E5LgF@jD7+T-+G%`%Fwtlhrx&3a-~dfyDl%2v=_v|jtr_E;YoOEYk9Ys) ziW}XEs-)~|5sz)7p8s2PFshn@x{+~;lphBhAXYl|H^tuh0^XmD{7U===Mtpn5`QUt z3E$W+jRLMKkUmsG&oHI~qHWKh0>u+PoSYy(pVH>bdLL)8XTCn*sks;8>?`E|M?y2T zeiMdG4;K^33!RV$U3c3sPVAtREeygYp|>mN7r;TpM_Gqk|180gmj5pcP%EZ{nC;ov zud%WVR0m(q-@fO9iy2Ldw!!ry^P{Fq!8amffYf1vXpN!#eD|0dM{JvIwKlycEcC_7 zFr)=JW~p8s#tJZ*I|<6B{R%a7*3BE<^SiO-T}F_#GoTansGPsptP2n|@F&n}MIVLX zO^hr+U9H~x_bt0{53)tcqTuuA1NJDT9BM7iz8{Uui`q1n266LYGg%Mqq5M+cB`AH( ziqqtO8`Rf0LgO=1+KXqj>QGfuSLyttXRAD>N(GClhj8<7)*9C`9Q`~Mk8 z;xqnUJ`_M21f_Nj6<*kc68C32z{;ztuz=_{K!dab4x&rd9D zL*M5iyhFnYO?@;vGL&yZ_>>|+7)#*=8KuYNv#-7O?;upKD&z@zyiiH_4Q#|Ejjn_6 z%-!RbZ-hAu4sI?EgfgP{8H_!> zDJr&6tr0v6x$CjQemX>WL_GAf9r@4#G@jFJ-R*yAefczN^=U|$SYTyK2vb=DRCYar zCHGSVT;_E)`kgv)@USP?8^Y{?_gZ-rM*5jp$-1?5Qm*Ho`y%kwi~+&B3QdU;hIcG{ z=97~>dnBCFb^b?BmbhlO-W@H^<2%Q<#v+Jv=UuguaNGeX1 z^X~J9?ZXAXYuc~lQJl}@K|SSesOs59o13sJd8py+&`Vx8+9(_Fh%EIrLPq^MF8?90 zTFa);{dM{%sjk9L?V#?5b>7!t7lrv;YA-SLT=a_tl94Z-f8PzA;pCC#XenOrcRDlJ zQ|@$^b_d=#A%OytyX-T)R)ZBSK5i|-;7qiL*8gPSXVMJn^!*?V<^fQBTn=(8L$CRr zaDt@X0#~j?&_zKAkw6yWTl9h&60ojGi_rwS+8poKe6j10Bn(-g^;t)|zO*6t7s1!Z zUp{=WArD-!BU0>_9o1#auWzm-k;Ssg_-vCGbqq494q0fV*FmNu?CJP;J_8HJAdX^O zLh~o=&m5ArfwTl(YX0lvXLL$~w291*A-gTnJypNU7A0*GC8-g5_vP4EfNeTV&&t&c zlC-q&h_l{h>-tV2xmUX-C^o1+F;4U>r`bT;k^DeDpa(qV#p%%AVwEZ)0Eu6j^TY!owhTC1Z`(~gENp$rI>%D1(; zvAQC6&SR%NJP)oMDbDGeU=O9Z<^6MLd>pCtEEjUGQ)49NbJ&Zz}QeKNmbKr5=3x;nJB;@pmP>S;Fn!fH!z4z^BeSGhCC6?hFug%`x*Rx;t#)}~(Yth~=C*C{YY;zyK z>wU#C=GS{~cS!~Fo>WB$JJ(Im>afI?))>~Q=z^RB7)Sd;4DqA9$=LS%S{MJGFpktG z+)DCKoql8-BcJ41N{bpZpi?0)S_-RM%h3=$bx2{!V_AoJ6!F_FbpQ}m=cObYG`3TIY2dhrT({4+is@UtXd~S?Sk_ z(ohG=I@E&`d@^l=F;!(tpXeUK2KM+4QZ{#A|FkaZq9leK``kjW%9$g{0isvekm2Ayf#}Ch42WKNZd1*R6SKHBGDIFj) ze398C*AL9YKf+2YNF+;X=S9lu_?nRs9}9|*86?wM=Y!AjnPxu(#A=J$a|OGQH6ofc zkH$x$keMMB35uj!cz5APA89(F>K%w*4W)vAEw87CJf(qfP(^D;7X`-^=`)LcfCj#8 zaimEUGh>G(0Os-9sStb1AIHNQwP&Xm9E%hJ;={**}t>PSg2OZgvXyI zU8@X=G!{m;$Jw^Y1QMjR+L``nLFYtGZLilP^H`0eZ9At;RwjT`(H=!%%P$_KU>68?hY z1WCC-us?&RxZpH-K218gSuaCtbWu78`Ip@A#z4_S0l>F({P=@{k6J%dwn|Z!GOyLD z1y!V7VUz>yYD<@~s61{a$c4s^aW+40(o!{Z2@`Gd6K?$_ZM$g3o8uT(%d6G0I5*N@ zH5DdDRWzqxb*Aj74B%(VxUqJ)1|jF%sKu<+)wG@>;<2nw;$jJjw4p^95t-k=1d3tE!Hk&3`K ztvqYA7vzFhNoF7QX(`?#J;8_WIaA@sID_n4z+YAWS_X(jeRuoCED~5igbrF>zjLd( ztH+kYa^2fzZb=kBCRS%~&p>%kP93uS^-hb=gS?wJAYq|b zlw#rxI=|9^4qH@00r=&GaFU7R_&?v_6a!TB-d z@&rUYhJU=|?B6Ad(5dy%oD^QC)$jauI)G^Pk!kkJV(*EtW<+mpF73Ze<%u?3`%G=R zDx{RBD%8v}SiU{}ofmtTTyq8AU3b~LL}l8K9y9GWn~jvu^-sGjhFov3z^5R*qB-{W zPBV6bb-HX+H*FK0)}@WDkm<>|#T1KLANB4j-F7W_T4Ii~?4pTJqP+tstO#S4336QscCz)Y(apC|n z16-WtmByz>;Z(|vws{5I?z7>=PMlA_BIM5hUG3bmYdw|ru@#43-a%ohrE z*uI({f^^@!!C0>zL_8MI(*#?E>T1!ekT38w6jlhLS5;Dc^uAjA@=0`pD4yu!J6kZ1 z*bByS6zrjw z%VtrnE8QB{;$M|=MAmS|e=wAPy-qWT91q!cC2n{q_P1}yqT{F`sP2+5qRWLx2=Soj zn#?BVCJX_&i2QD_Ab1ao$0=#aLEs5NAJWB*#WRj|WWcrKw^&dGEPN_u8xrtr_#fGs zuXk-s1ZDW!4ile_LH}CSvNYvGMb9I+E;|34o#;fbcOY*YC&@BZ@tM=RpGSzeSK{Ak(I1=Wr#M3 zV}IEo;^<``@57wYB+HxMS>)I!{4WOa4Dt9^aU`w95bLr;8#`W5MP?vg@yMn|B-?Lw zv$vKm6Z`X2S&Ax_34LtPG%0u<{F?uPLB&~6~5dPmqU5I^Oh+E#ld(St4ItIpkctydZ}c0vLkfmYrSKjTIPag zz+um#X$*7Vpl_EGCx?xOnNM1{1#=Pw{O98NPm^{#q63-rdACxnNW;l zGeeCuTICL@5AW0%A(@2OeA#?L&8~z#Q=-omT&ypZy_JDW>dCWvnf7tn(T8aNkuZrWkdQ3o{()4jrnPfprchdgd&Mb%?-<>!x5cY8 z^qg>zFse5VB0NT>NNALHe6aqmr8l{Wq5_c5|9!g0#z}*Szy9e{D5Kmg+2e3jMX#cS zJ1>-&;|(w$VEA(tS>GkYL@ODyLi9Ph2B7Qk!S?uzX9l&r7xi+>HWin#a_<-Peb%_h zfvQpBhpxm#UUQ#9*(}v7ERnaizo+!o@M+=@Na*JL5Z_5-cW1;FK?umZ?$|_qH=lRg z7E@-^vDq0nX0t&hU;v^$b2*))8rtb=Qb@e$cnpXE{inifsyD9pfQ5{Sjd{+5uQ{@7 zW5iw`h%Ds{=0E?aA4A5(B&!o{fh|L*B_7T>Z+De4H;x zJtCB&+mtJ$R|k~&Z%o|7YDRwuwzJm|{=uL{wuew7vn>L2enlM8j1(ij?B-Q=`;rAA$cYN zyU>JKFb1>poj1N)7b#ocG%PDT8LLQ0joGz2bWC%U`Ni9I9}9?N%84;lMu6gk_>qz_ z1w4@fn{(3;l8p64{HQT>sLItJ@v>2QEWmp0T|crg-vXsFd6iJ&=vQvY0%6O*Y!dq% zZy&1h?i;IQANg+&?p9RF-y{@2J!RBOSTwsO=Rj zUJGTa-c)b8LRU5cX$ir(kDjQDuZ#Z;z}bupF&C{vIWK)*poQ=F-^1>XInyPPlHXWu zd5IcyMO#8XPccj&N^uiIW=z9R1pYshQA1{o(%Z$1AGdwIH`-QDkCj)9ZnH zR??$5RNr%wTnL9yo_m-nPH95S(BP!*LJT$83h;81{rAh?ug#7D$7Z>}`qnxD9?r3+ zj^Q9qUeL!LVtqBg!E(A$rpI5jc+9~Br6t2SsN_N)PRKSNf(w2C7a>DHESpdMNw+tg zIJD%QWTYRkue2PJ7S_J!Rj>SV^a_(aKWJc z=RD^kIn05k{|R(F)c(~@^y>XC4la_G@9N=>6?k}|K3k*5T~2<_+g!FgL3mOLAAH@|^)#k|{Dp}_S4w?FfHh8mgzZ7q z`vM9{Vygmmv;YCmNd%Uq-3!nokm1_rKiTWGPJ^shDO;zVxp#xJdcqLR&!RqVwdB zl%CN#B$X5`qCQ72m#i`r?pWlTldra{(fM z14I)!w%1ox2%9{(;!k|f?_ra>V?T+kFkV226HkPgiaTG4D)VYewR8b4aic>|=ma*- zbdQmSrP>Rw4fcH89uYI4x~WK4@Aba&_X)YiaYGUybC*rm9qTY=L7-epM>jWKcna4vT*BNF!L|jp~ut8r)PnSX|JC)xd=2o zlNLKOl_L=%33%{~Wot9tfAPIf=b8Qe><%lWq8o7 z`23${1?eHKRD~&m9tVH!FpNlx?9WS7W=v0rlXd-gN5j0uTPUJ?A1i@1(c)M)m+M1aI%hX;RN~INpoKB@e&U9^er>Om-mO%G z-M%WcxC3v2gG5)>qA%I`dW6q&edylw@M3oQo-2}C!F&TmRSTn!+HPdmt!-})FO6{h z_e7YmFmdmiL_EFj-&-gRE@ihcSicR;m;k=z2u|TizH16Ll|_9ZYX~T{e7_Lmyr@+j zE4@eq8OUIsW-e4c(v6xn~;_Bq@G^l*^zGvm~;L=^c zIk?pT%819l0|~yU$B_^RZ>xQWL(EV8kD*04x14Er(R4viBV)-j!>n+Az-QUdbddnU zhif&<6J4Gac=Pv$yUu>k2@zU41}nq#kouflcn;p_mFAP*eM? zs99ZV9eCm`7dGJ#!OMf3Th9JZ7Bp+^d~Xeit=G8dG}|RN@}Mfv=*zculccqMWYgR) zaa9PWQBk%@8}qNDy(7zLKquO2YRxKnlUS&BFWxH<-q7X*x!61%Ns58koA#4vBbWQm z2lg(u@Xmv7lq8!QuSX4)sb=EM9!aNPlu`Cvh|)&hW1M$jTx?y!QqNAT1w(chgP7W` zAC60wsDH~78D&QgH~o?=GBiB+k|Fb#9lXPfuj88GFn#Up%VcUtt(DWL1Ta^=J3a9x7HrO*bs{Kfunw>Qn(;$fLAyetROk+7mI z*WWGmwB|x@aWT+$2pD6rCb3Fjp@&B5xNQZ7d>^-B%^4^y=i=TG4+uz+Tw8>@2gAE2 zKJq ztfhhrmU2W^;|-3Yg~xrlI*n!6f3mdITW7x9V0e=frlUbLLDT3+S?dY2mB>Tq`5ltSwSjN3PgEjynM;5IT|okA=& zv)xujExaFpr(pblS%8HuWm&!I*Mt{Jb`npS6S;;T78hLR=R5r1O?i(etr%IBYzr1$3tt>-0s$UDENUfASh%!U+ zo_;M~T{&T)I5Y?BVKXftSq*BKSld6!P;fwXFC^4CtS0V5`}?Wdc**wRSebNdjvY0F z0g!RTwb4_|-X$}j9v(#dl>+sj0W+BCSnLI@nLv%n#a+70>Kvjh2lTYpWGsdrhW|wz z-eD9Rq4TtyK!8oqHbqSJAP$k5iO3%@`#mx!6q}j6-#XDOU~xb%*xWqBufk3sE!%QD zBPAo7l0F35G5V6-?>(&n>4f$gggVEe}ppVN#y1iENDMf^wG;Voo%M5SkmH(NDfwt9(H<#yT9&i3Z6eR+qLYjk)`{SQ;ZQI^o%|7y zuW+H`pGi<-N=om1eKyg+FBjHqmoo@#Dl)95o@w;V*&RNU@C^#R7)el3OS6Ou z=-VE%&v`L9r6^iB)w`CjlTGncSR^O8^)gbmpwQ^Nq)8*s8@HgEz-2PZr*eML?49gP zva77RiMF>(W!D7chfK{~OS;Fk@_pj`^$*Xud8&;7nwynQ6Ww=djf~Uh&MyHWlB;X$ zBjJts1a{VOP1Q#NA+UwhyPi7}*q^7+G8{H~rqi{pKVI1fqg>+)jd#ONH5J;;J}h!yX18@Bp<h0^E;mabBD!hdKqWcj!`hTS*$Wda2FW}9i( zBcznS3vu^zQ5Z@JBoLQ!R)X1vkIcsj^8%} zWu+Z4!x9?JvH|_iZO85_JW^$%te6%@52h%e5Eg{}jnS7^j!&B#=6?r2e2(AayxEP* z%AEeuN*9{WRsaw}8RmtVIrLv}+pFT0Y(FFUITiy-4w2#gAiOH~eU!J^K<)zVP}A8MeNMo)e^t||#1VeCqWXA_143zOc~acdNm$=sXt znBy!TtY)}29?ZLvgXJ-Mf?RKUF16{uTfJ#Dcv*bS{P+IcF4O2?Dz6!d#ZVy$znb0F zMVMg0sb5Ta+}gH`9;-jv7N7GyHm(IfYH?aj1vkL5$UNs=W(HXQ97R2|vZO5@2P@BE z_3i2xoI*#s*d8bd#m%ahq!VFE8GY@A3b!v`}q!^C|{hT=$M;}g4e(@i^c*exyFcbsVW zHfL_{szx_%1WN4oUY0C;@8RIb1+yC>BLek$t0Gja$nfc8TkT^v!;*3I+f^zBU?DeF zGFdn`L2ajKJb>5fSgQZ~Kfj=4HYq}@czCgkLNR0;rLLR;eVEqYywws4$OpX5E#ht* z&8?xqzM|vVb3ZjcC}SoR-PjJEeY!S&7d6C za7EQV=y&(tkRZ$6?|E(?02>O%8a6wVG`m1qn@mG21%scXXpv(F0$!FMc096)HF%?$ zU_*EwDZ2$r-ELXur;{@Y6XZ615kjO#%b8x+@jxGd3@wxZ6BoZGjY^t|fZm!nErUZE zaB)4@nT;V(*YoxlK4IW$de2$}=xZFS-~A-r5%d+BD_X`^b4L?bUJ8NPl+1>N_OrD= zs{GK8R4%KYw)Nmu$mQK+^X2x2;BY41QA(dv7;QvdSoV*emb({%Ad=OZj{7fxh{2Tm z>5C=7J^3JSp^8#wjqffret8?ecG!94uoF25>d^?;`#$(GgqvF{#qe}!e74-ibY#RQ z$0wu5U&)#hLf@tr+v9a(3^~I%HL{?^kN=vrQcwPd@9P$k7*$7hLbGFsaD3qfci}YM zO`kbc?0CtzMGg)}KTbU+eFG|1%=`LRxArY5fh1TiJ>2@+b^Zs-0d=v==@;IJGrCqP zU@!yP05AGK(GHcRDq7DBlnx2M9v1@_YRzHp-}g<;6IYtR5`RpskJ=}?miy(h+i>~0 z2J+Kslq6p%f}%wp$r`%xuq&YhynqPyb2s8V30j~@^WY~ynbUFo{nd#JUpBKqtSLj` z$tWzzR#LSN+SwU!Kx|pmygxg8zqi`v8KU>HP*42z|G{1UM{17ra1*3{Xd()qQ~E*2 zTL&H&2WAc89f(U(c#%cRJ#+N^#PON3>`IBr6W35w68zYmC#a$6skOt1q?RT$Jdjp6 z61j*oA5VOd^I4PSv2hdDdRJd5nNA7%Tz#4>m67K6!>Atwh>xz7!u5huqGrUC@AaL6 zRO@@rE%yyU?rUC#dXlD-YQYPS`?zQ_->m*6FYR~rh6p0epE!eW0b@JX$ z&+j$y4+IeWi(ZxejG*%o@8{hwvtKkO+}`4cW$O-#S3{Ma&YB%1s#S7Q>0+arO`W$b za0!{m>9)$8UI6;WNQukXVk>5Ae^IKa-Ned%fBWmx_az~f6T)`CV|~L8jr5NHhq12; zYBSKf4elj46i+Eq+@ZKjaY}J1P+W^^aDq!H?plf!O>rphP>Q=3cPDUj{+auD&wppW zw`3-H$j;hp?X}nL6sl?>n^60+5!VW}Nld*A9f)!!`+PW~JMNGwppr!7OpQ#nWJzEh zTJGg|787+|{TbqZO+~3;I!1U~5$gbnN?#x+P^zmktha2Ki2(d0L6Ry)^QQ&?2Oqvy zGHu;oEvU7om;Gt@X*;XciQeKrmx$(ICB>K^mNBL=PFhgDbU03QmGp*bpS79=2CYob z5<<8Xxs{6G&is+qWv+GbRkO=J=UAt9AA?-lcD7flO@1}2KIh{-7w)7{_*KA)~=YyR{gnMf}otS|c{|8v1(0TtnS=7JbmlKBFxl8jW z-mE1-XemeM>fe%1cfY(Q;1BNq4mMN&12!>N<%h2Dor{A#Uw~bPaNtHGC;VnCX9+w@ z{+RWUXIk!f*a`N1x=I)ySMQ)Vhw6Ay2X{<{*F&)+l;GB^&qEF zz>%3E{@OT3Vt;y5U6c%59k9lk`dV_cZT@MflKe%=;>g<7qYE3Uw{gsH=jaOTv~;gP z2awX+ZXWc6qhVIu5dnir5=6y5TPs? zqG0r(7BDwOK)zS|^9f&XZO{1YR`za+6<^!(#hYg_!9zhoUuHS1VirWy1r7%WL>S}k zq6-07F4Mye35zugc3WZ=^^2uSTNOXZ*T4a}xL#pJ=>fumn#&w!eK<%~!m|6p_s|yR z1X`FOim(~-f_Mg$FD9YBoh(E)d<;9CA;BS;%!Jg4MvPK$ddTdS*O`i-)+?@y-QdC_ zbn?@gD%SZcMrFIKZ8t0J)|S}z3Owl`7cUx2O_;Y5E;wch6S9PgxVR9k&%^&>qedXy`<4z|*t!l8?UQ$%+t9Kp!l-Ar2FQ6XX5s zvou8TaJtMIb7N6XLxgHz%H>ei!h9qtC)090F3xO|ZF}kVRiRC*T5{a*Obi3{v8cUO znTP<5;he_NE>s0IN%dlVsZNqT)gbpAXfX~7VN#^lGvI3bc^BA~tcV#h_E+D6d^Btw z)lnv~!|DrqaaEH1+bF}I6NR%dniFr*R(-i{EQfu95<{-790dn+!aZDW5v;@}5aWm7 z%u-j6tv0&9;Vg_j2Om5ROwix#&UX>l?(qdvf8p9<8*Um9eHn+Aku|3+m-^TN?z$*tTR&{=9W zI%sRaet2@(yX3aH_56o2`Q^LXp`hBo)W9_GT7XkkP1L4&`ppl7+MrLw5cXBvr`7hL zldNwjg8Sx%zs$V1|M||w;?yfv;3hXGPaK{LF}il{-O-uci@$t)(*J+yX8*yShqQS4 zeC2X5LABvaTib(=4}7{hpwY|pX_?G<)#q4!f%(2&mapw(yv>VNjcEXUadfwD>Q(JH zJ1dcvv;1D)xMk3-d6VKhK0PNQum&)4J;Cv0#1ZJp{RQ@8UP0UVWuXSlQN)I%m>Te@ zlXzYsPag0eP9xhZ8HV;#N#M?(d;TH8kr3PmXfQE#2BK?VgErA5ty>n?GFZe;BbyOnX#O-QweTt;ASeYm`7uWS`Yw#@lzKTR(YnV(Rq4aWEtzag_~@}@w*>>+H5So?xS*Sym6y0X!@*RXH*}@{pDxMJ`F)`QD&|m5otwq;tS_x6>K+_^OUr#B zO#MVEx|X6#YJ2?#!n`-1tYq#&+7tf=xPt{z@}B_`F0z<()~i~Nxr!M7{d)?=rknEA zB(7Oq^eC%Glg4ZqWqj0`Y!qDBDH-NK|I*d^Q0zEdLy)nk=STU=ml~Sk+^2K{WsG)P zn>|I|oV?CxTP-s2e+fVc2gdt|lYiGT2dV0{Z8Q%ehbS6XNdNk-5p>Bzw=W+cxeA*x z_k6~e+jgYvyUpl^av03G1$r{-%WD;+S#G)fZT;esiTBJ!U1qYr=GGc?Q^A~~2${cS%|D!j24WG{8N3+H=>HkWJ3P!oAPyh~ z6RTI!40Yw9EH0U{&*gCqktco&och*H41k1PmS(;<2unQP(^ZFI%5>$Cf~#jGN@9eg z6ep|F(LpC$>TJ4FtpLOaw61$lfH}xek$$_}%A1gfeA)fkDTs^|hoT9L$JaN>8*xkSwyE^17Jf@pTVy(eg5UDdwQ9 zWeXbD{xiUyPdH=6-mr7ePSBjFSwlDJZZ=qWli3X<1wr>t1pS(KH!M(JmI;g8+ ztj;2`E@5V-gc|;p(BkMW-^<7OW>D!Mk6vw3M`k>G_%>*XnCp~b{Zdq+qHaPtOAifwP-$}-VN8e70Lv25U)75 z7-1z$N1o*$_9D%^>U$Cl^7?tP@890-F@vdcm99LuZ9kr zzt3Ri?LRWTys@%4vUfG`&xp%uE%pD^*8U}L;Wqt{`ybC!vCi#+LJnDi+=H!#0lw&* zg~on0%!unGEyUJihr_$`J$gIG9TVU$-^`G|=QEhXUOg_(q=mzQsSrUhUan?Ojzwgj z8vCBw+WZaEPENmiKSpJ>?e6_Qhe3!J{^Ilf51kTy(%Mx2Eq7R$k^6m9 zx9ayNe|Yr!^U{ju_O>QC)`>w_0Z;qoi2F=?l9I$NdtaKLqjo_5e4iGK|NM1uaNd!T zNsM!Sr}P>n1c)4STgoA$HTK))7gUv1aHS+0+Z*E@b8nWMbd`F*^zSjdzv^n-0k@ww zOI3knuO*ywGO}O_JrjYAIWv@F4lSy(QO?6`!wOJuu5>(%8;6&hvw!_@PrdxB{!gnL zfj;qZo*Y?(M}t-}yL?QF`3$hVKBtcFWNq4cIZoqw)XSKvVx(A_JoD+TcDaQ0TuDGT zx7z)8z|*6rg`VIFt0dMkeO|E@yNdl(Z$SVvnk%TAq&hpU*UyDY5EZ8fH60?P9EOZ~ z{B-2GL90MTg_oS}wM@5^!bQIBzbM|}_pp6jqqwwalO4?FRbFtVE?n&Q7Rkl3+?MQi zS3yB5*7KE6)8~8E0((39s@hG;@`(iNJfZMSOaHyOr{39Flau&Wa0&!JMu-v>%J35l zg?n=RNAJXLDc+ubqxXe8-NJVISJ?OH-K!&c$YR>jr&Kp{bJI_*+#La^7HxNuC*GP5 zJ}kuCu6B6bUi9`b`KX^~RQ~HJV!YFJ4yfFcqh=Oe0wJ}exWU}1$qXUAETd+ahQ&6+ zSj%m8o935Pblm;XQOWC;+;%ZgKMs!5bWojudIpBlPg~S@^F*>cA3U$7{K*C+5S{rZ zLx>VPbBu*{!RAsr z%)IdHe)L+96&V$6Iml6yEw7!biJpFn0bR_u?iRna?W0UqA20-^eaL~g8`opEM9Z|U z8OKP~MoXnhv_d3xPhVo%t~Q-Md9`4h)tDX~!|2W!|kBSvdf( z044#Mu>YrFBvUe}BtuTynmBp>LIK{)yqi{pq1(|Bmh|=4OrTSOC&?e>jM_~WXTpM_xZ#pcIhQhojCIjD(B?&?f5$NyEv@?FyCzg#i+o%=f_)C?g0N1IM@;EKUZ# z@iHS=s-iSh8XuiseT{n156r=_@?3ni#{_k)tv6P%ZB3`iIYM7L!dP3h5%jPTwoM?l z_0uYNx}&fV>s%iDdbXhv5Pd01eS^cJNyh#fhmrC02ir%IxA#B8 z;)WP9x?tNC^+Ta}FPei}|JF$^DVc81ckCttOP2+lIRu{e_N>(dW!%I=R|ZAj;@VP$ zxG_j6N(=s;&vP;6vxQ_WY)joAH7x(~xYf)<{aqxogeBhw3+3|h+&owm^Ky!f=sU4@ zcIqb;3h-{RVJz$3MM-Z68pCxkSM_;Mn=%cpH1c;>|FvK)6PoAm^V(Tf_3G}gd~ffR z)y9%fAA0RX1S~gVT}n1SoGdjWvT4Off~RP}@%o67jWQmj2*h@zQxF)Xd_@`$O~)EF z1}Nk5;D!OPXuA2iQa`^znZsmIHUr`4Nehd-X3G^>)ip8QIjTsgV2-SYAuq7&6 z1WIS4k7g&*bg9R7(&|p*FTR$IK&C)x!i~opG$2G#hD8h=(FUGzq)TQrQ#e|;X3KZn zul}d*)FgwWQb+Q6}()V@!#Emvc{z9nNw4@J3H_DrovHVceQv zb|gRZC3fJR47|6c2;~qNtFV}yv2BQ!(hcA4d&m4K&wj+M8gT*XKmxxtt6h)ic)ZIV z@eb>ciR&Zx+gam{V2S8t9vY!q2c-+6_i%wL*`>5DC>_xY-}$o+04GcC1+jr_dIKquFD zgoK}){VlDcYmfK1;L`p=I&L>V$-Mluzu)0ec-l=oW+I@_nyJoJfZI=CDRxjVxhWhK zo-QO2iaKS6i_cZcmAGnlX>*ieNyZ^R4e2ZEGRPQkd0peitsT&eP(V=C$WG-Zx9! ze1a^sxCGd7OoFV%=^t)eU zDBvu}8$g(JTkt(0Pu%YW_dL(ZA7s-amzd#MXpieO zHrjL0|Mdch2ZUPKugFnDiY|DnsUNDg%UP!X4hT}!u ztME$)@0Z@32{Kg=|4^clKiFiGqPGfRCu7LHlo1%_ABC&97hK zsw4d#$C{Hf7N@+sPpa7d=h>i5u3hY)WiMnNq+jfgi8BxsWbuYdA%8w7?lU=R(uvRU ztRe*;1brwZH&tET8n4k=-mouSOf@TEe2swCKkcJ*i{mE{a=1{mDyG_ZQ+wm;km@Gk zJeU#sTdwt`hwoJ*uyhBm+120t^g@(wg31?bHma5ZhMlY+B;&jxIMS6x&WOPEV}E|d zXZ036v_75#hWx{p$HUL;uL1(4u9^>x<0Uw0Z!hKto2@$1bKnwyc1pQ(6muFAk7d~g z+oJ8VCePES9}Mgr!eU_07XMds&ZifbetmFLL`v3waZMaxr2eM_UuvpjB<6Hk=6clS z$^6C1f}M_+SDPO<_g?DRXyF8)K$n%Aa3HCU@FUJZB>szo4tuV#!E@WYbOUy-L#!~nz>_;VH*y|&Vj;Y_5hmK%$IK4nK>CR`{B5x*I z2Y4%@Ar_Hs@K|w;8Eh*jlh7Sgdx=Q%e3gXI>vgUcYraW$F(h*AGJud;0I3kUmY=Lw z75O1Me^{Vgzy~%5VU}M;|M7TmplART1)SGjw|R4_zp+Z%fwFzK-|*G4n#y;{p8TDd z=(RoaU@7?PT^0UB^TXNTY{CQ{ES6FPpDWf)R`!%3wbRfoHI=7jdVE4~NS3&b$jW3p z>ye3y(!rTb8z7Wbkgj_#&J<2??lMDFP|o13fT`wh2(1}OeM5!)Cm40X{nBm3(rV$R zN=cNw>Db#Jc*nI&-f& zyWioB`lz&}S*)Yur@x;A+q_*leK~oEJI*&?VEc#7SxCCO8aKuq z7=?t~z5kMaS0^J*(3+#-w^r)#PzKbE!KXdNYe%_4DLGYClEax_PYj1{t;7A-7`Qbp zKMjB!Y9%*~4u>FHI#Q~}CQ;9~p8`IgeK$bbV;TLlEMFwc{H?*s3f5~jvYn*lso+MW zu*#V!^mlw-)RhsoE@VD#p3X<81`2zx;pUA-F4;YAYw&@fI@KunomY>RB1RIUgK#C*RW?EM618x2-zMk@_h0DX$>~DP zKpy|Ws{D*0C zVupz3?bN>+K|uvd?yQr$A(U-d4b||hd$tb>MZEDy=lK_A$}?L`7&9CCqi+NFAOe}m5-NEIwTd08^i(|XjiaC*w#%ZpfoW7}dRO}T3Gqosw`Zj)BndXPj9je+P@U=^QuZ*5|_EF4|?P zUkU_o09}5kftO{QIp#gv+^$rObV0F5djy+fpY_GxFM2|Md(L@iJ9h4@3oPG=cnL;P0=|k z#%n1_&UUOO@|R__tL2LWoUp(qG}=3>reF8pCis<-Ld5UpHiv^ym5@=sbEbJ@6(TB%pa>HPPYsc=V6J`nM)mn(mLWG$y9hq%5}$FN)j|GY^+i*yQ`3@|{YqseoH|ZzAj6V#~;>#KE6C z41{V>$ypx#&>Qb}*VEeRnuM+UAlp}rcuWLB3EfJl+OkQ0w^yO}i0gx+De1HR{Ml^r zEw@^odG@#hr)#utZO!!5Vlbdeb*)n39O~IL@bt z_AJgP3X7sOBn{t{9O1dZ$ET}*394%NFS+=uw^DDn5aT#D6b(>8;5i~qu+a4R=#wOx zUN!hD-R9(r*n`c-heND_Qwh$#ycPWIOvI810dlV*EjSuAYo~~IB6>{1(($SYe(8Gc z3Og3r**xOpzkZ^oC%}vybW1vZzyV?c(p%0**x0I>s^H$Ek{@WS{AWXkb>>oK& zUpl}~3leKnHoR+r_p3q)>EuCV8i4PfAqSPE>&TlR=Y^1i`pn^?fz@9JbZR$w{hH@& zAL`oEk5?Zg6nn3vGFBz)^^P=%4H=Uso9HQ=sFhu=tzO3ucnKW#W6_FcuRt(FnyU5? z$mXJhbA{DA|hh+BEfcKKe_1?~ZWkZQAThg-A zm7l7@a^ama-Fm@z1n8kU-3V)gneS7`T;PIvqMyoIV{ z*vsiahToa=hltpk!`LlM%XwHNkzH=C@`V}M!lzeGh7$0z-X64cP&hT?`sdeBoUCd5 zyf!+d#+;3s4_k0MtTZgHi0PbmP~D2pdtvc%R3M{C)&}w9#fn=kcFPTE;EA6BW17@* zaTTfQn@tKzzsE%nl~QWTGSgbu7E1p|r^HFNrO*0J=_9Z+9`xg^!&A!8>O$|zCizDl z4Yr!Om#>0+$}2fnc~Cu$#LYi(rmo8)KXd%g9EC-|Bh5FoeXd`j_XlzxgLo{8Y8+0M zAK3d`E<-P&W%zSWhdl65UNd2I$on$Pkw z4RCE}e#zs_%6n=M!Re-Dw}MJY2>ab!2j06;1elPV4<7vC1mEDKjgXASoVFsEBT@s7 z+>~6=zZzIH9Vg<*y!gLDUBkXSvXOw5_xqRUOqhgv0HT3~P(E6CmcyvEIQ&RSBPHHvM4SpBF$xO6ToV;X+YY zwN}GL#MIaSuTR$tqrBitFU2H3WNcX`v)|CZbj+Pbj-z|?Y?3J{PpS6Xw*edtn$XXj z!<_D}1|-h02c?dmp%B37At7=`%U1(urmsI+>y7y(ef_!CxQ4jwMp!0jI`e*g#U^kD z7Ap(hii1uM4z7MS#y|(~1MebltTeMB7?AXNSq~~}JOZp@KlYr8xQbF?0LUE3Ea1S> z%M#_*EJPdDOQ7;0BE0>Z5ao=kKxHT@b~mNBb*Mez+Fx#^GpdqvCF3^Wur2iM^MVbK z(*(Q~1Kv6x8c1(t?)v;f}k#9wQrZd+^W|6Sat->OI4CotxZ z<9T@*Kp)sM_jr6y$Er$0KjXi`^(D42kqIz0H2-{}2Th~L z8w~WrwlllT%^MiQMXI{r09a5M&L&D3Gdb@9-F|a;xVzY#_p_pp``qXVlk%(&HqCS^ zZ8GVs1fG6wW!YOu1KSvoIiCmUOa>9Lzj;VPOe}w>!v&hd{Wbb#epR z%dMT67VZ#Y$UR~8ohV%ph%!L<_35)7qFdWC_q?eG{kd{xB}|&+OiGq)ndsyIoSys` z5edfx8HcqzVITaM2;$Hfz3>p8jXxyLIW#N*|vEM`Ku^62m{M6aSYz$)JJ0O>4lZF-KI)-TyrfE=E7{ZNj z1kTm%R2#90Qld+A>eg<#`{p*H)d(VN@vJbE4`(COqG!MiSZ&P4BE~ch(`fK5n0v!a zU{$9?MNfmPz}eOWbG3)6ytKXw02~DQniPqFzYgx(=uPZRHLxd@xZ1~LXD$|bko;i? zB_KGdp@mFpgw$Q5B&u{Xbo}_Pud*b{8t)W;HYK##*ET4)$8`C0G}Zm7)(zi7nBLsU z-w-dLeXzTKWC&W@d~ep`^_a?OdUxb3LPUYSS1cxWBQOSWe8)yej>;){7H4Y(MM}C- zpfZn;rNI>-{f&DbPfv)kXYN{n1U=l;ClvUU4#Kb+;QHn~+|O{YAK=-A9@H!6Dv*U+ z23@f9V*>m7?R5)Acs{Lm_uz}e?(P;?L4h*Jm0s)vO6MBsTIGuqnSbROseAUm-O0%? zI!*cprK%g`ttH33!vgXJ+1Dzsk_V9oIiOO?aglzuBNtGT>F|T`2ozX7u;DlI?$Ltx zObpX*x5hpTyv}XAE6K5bBNLpUj{4=T_ubz&{<-T4?9$WNk__VoVp&mxpUqW});?}E zW%qW&2#AdGhxsn97|rwEOYD7dwe|#cH6q##?%L~YhF}O*qLYBuIu`Cv0?z(cGh|oX z-ed^=O8EixlWTY)A%Tw_4XvEuGH>eoKibY|kUHhlU7D7Pb%=LjU5(g`0@G1E(?+#K zbl@gVqtE3xR4=C-(&^?G@Ivdf-pK4z$6@Eoi%%~9@%~XjM5gmhJB(>*<-{Gf(nORs z?-+@zWlsFFJE)4;SrVBAi6s^EwvA4Dg9H<~4wF7V2*|K*wh>g=YlZ=HTvmd$F3GgE zIoEYtK*vDG*XkoZ##bv&vYg?Q+3ykJoYUCv z>cB06Uy3Qh`j(qVbYREX2QN}}M8PQ`{71+v7P7rK(2qMU!4Bg}X2>y;$OIo@CrZeK z`{QK2D@&1(koD*Z-`jiq6?Fy(Z06yLY>^SJm6;%p2$A1BFm9 zjGiolS}$pV#Uh+v1-aN7s6&S@TS)#U)O*rCIgvE@EdZ~$ZD_qCPDG{tcAgje9TIr$ z$!G#m3pj4yUd^?dbvP^4#7aHV=vfAOUfEaNFQk>V&OIw8lYo;U$rZ1%zdcw?w`b*1 zsNOt3Y!ubNtz#~W~h#tL@W!L?Z&N89lO zHx*QqU*tfG;2EODru)A8h59_FOgk(yBHa$Q=jC3Jv^j}ZV1wbql`Q;XhY|1=+n8%% zApf5(U#pEf>vJ*L=EP)Q4w?RUNdbG$<;eV%iF`wpFX+ksLhvF+B`|9KCP^f9rDMlr z%H>4F`fDJ8bSJZKpX>B)`r}=_{cbUSn_fQgJXhrFTnJj&q=GG7sU-YbJTQO;?9@bV zN(e@l~H){+&r}KZ~LLE3_EiQEgvZeO(RDn?7GlM+}~O}`)Gcnd+cLa2=~z; zz-gEN%N9W_W0x~Fn{*s%E+MKlUV}Wd?%DB=X0fr(HjCfopY1Bx=5~g6nNG)?N&LJ* zfU;R^isqU}ot_-4)ru^pG~(pP`Tjrs9MkerGR(j6jUBjS6w}c|VEiG6q~=j^9%Jv& zkfni=$UUvaekh8!M> z@oR>(v<1c?WlF29Vq%5V?;na?<>)Nv4-lOn@<(;EQkjy{bfv2PV@LqB)as^>NXUr) zP9Wsg7{H2jw^1{K6a!d*&?k-nif_qo+HSECS zUEmiDZ#@dp3cPr??}+1Px~D7Qd?vw(OPAj)1#cbvT98xTNd;aG{j<=}OkrSQeR~uN z^RUPm#0YwvAl4*P_Poq6#(jrGrujC?eN75ra3es9!_Djn znmQqmYUwHEpd%?b5hX&^fD4DC6}FTCNejn(8t@fNMV;Ki37E1W_#D|(Vh<8fzL%1r zt94TWr3Z|f_fCK)fuT;n%M;l1zvt_NnvTnB&L`^A%D$M2{G~Ki;^+@^|6i3_t=+lA zNf%uRc4|jp^4F{KrjCQEnukU~iD$7nXYjhSP0kZ40iMZ?EeSs&?ImI@-|9+PLxx7e2tEF62->np(VU^g%g z^*qcoJZD1D_!IsE6+%dWCK-kLZMR6Bv}fORa?zhwlG9l1dc55@Z4V5q((PnP1Oy+< zNz`DQwo1mddXt#ZAN>A=FyQ_ERKTa*8_~y)HyK&2(oK#6EoMlpb~_F%$&$R;gnd}K z1OQTIE9*Xf*;0Dn7T~65Btp)pZ-)&e!98 zw)Y0!GX^bvd%HCIK95)fS1Z^VZ6ox(4Mf>2ixBjcl#c2BP}=nQdQN~-9@`(8CpG*|@%G!rKlqXL*Y{ulWtP%?W41yAoyg-v zVM(P_q!QISGSYL={}jqXg5z$=UCgM`drD+;m@_aYYV|Julq3wxM>UTWbfSLuP2ZW_ zzy1~MqenK+Z-|T^`#|$h{l&I-EmM?jy{wO7n%Fx=CB5)2S>ez zzq%ZR!V=+3mBei}hA9rT$AdXQssdxYi_!MGKE;tH=kuX4x7;x#p@&>lpUtf5V|T?cZI>8Kg!c!#7Z(IjMgr1XX%qtb=w!^s=;Y`~ zn7gzw*>QsDg6WYqsr_vTLc;k-VLt}i(i*o>T>KBtHw1}N8uQE1XnlLubHUMBL$B9v z>0|t82mc`*Z=|W;p7-5zbadpdyNdLNMEsSucmAqj2T2b5rum8v%Oj?k5C5jrZ^Ydz zlf))JuUgtzQ$1d0} ztw^yj(BiM32u$@FEr_-1N)>2)pWw%J=>gr9C{}rYQysvn=<=s8dnNh&G9hp+KR`hr*lY~4}E2goj0b$ZZik%<$c&c{n2nGvyh9Oh-+)hEEdgX7ww zBwFc+ak1Efc$7R@Ss5j&Qy#V}{!1|0DCQbWE$!nPy zqA0tL1vqpd?yZUA)*=pnoiJdYjPCms3$?YuKA4jKVH-%BDv7VO?37Hbv4$%0hB{=ENz@<9mmLm z`<+Ddx`AUb>zfsA|Mj0ccJId~J_g~b;;nu9+mfn8sSB+x>oL!P1PV5sEM0S<>|uQ@ zjB3Cx&^+4x@Rp^G#;Q)#|L%OMdjQN&ffvv^8)ZC!7m_kG_>qj(9PJ-Nx4BpzDi#`x z+`>_R#$^S;^p>C3e*4NKs>!!lCUvps5U$re@ixdJRFW#vf%*kLzVT0uVs}4|Z)o`A zuAJUqp4_!`@vwXuBCm;TrnA;6x6=BHHn+)wDf`ear(+4+qyGe4Bu%0G`Dx`{4OcqK z1HHzk3cV0UIjRGeIIx;O(%tW`#u8x)k^cjfqW?{Qs6uRLKwPUAZpSCJvskaQET%Up z6IwuC&tKioDxt(kvKnmUwdAbt^pvTB=;$S-M=IF~wNF>)b9SmQv(0~a-6+_NQVh0s zk3xRD6ZG+H6BmE))Y7Gi92~->C)=_HkWqvTwATBB1;((}FE1}|hM;96NNm!$gvbP% ziDL}sH$DY8yfU3lL-c$z_j``@&s7cSPxKba30nu35FW<+Ei3C6zopXWrJaW(+UTyr zQ!Y7%Ac!IzT%+85FZH>2dMD?PI^<@rw&SoEu`*$t|L))WSyi3I1TvXob)yoIEgr05 zQ{c{XAZR7?;zmN~XWUd(NHn0qBv*o2_pIo~a{i@vGWX z`2Hny;AN_Q;FcDN%&$2sV#UJG_~BmqyMr+YP2J0DU8$n~wcOWSU9tG03*(Ll-5#4% zmzx9Npqt*3>xpig_ieY`>QDC@-Z$F4Pg7}P8Ibv=^5@n4dIfMhTN*wrRYEZBb_IUP`^)K?VK(>*{msh-NzWc5+28MGl-``C<UXuTO*<0Uhk1(0m3*vi9 z+&<(`HnU*g-spB-)aJ}d+_<}6p75Tc)CzRZRW#^}@_PCh{PN9-#)N8tR`)=`kJPfH zsO+1nFC%Y2$xd<&ok*yO$XTdBte()NvLTm&WGz(4*X#H8yG*v}N1W1Ug(-J*A*m2z zrSHr`*W<_BU+SZ_%ol%j|2;V8vz(?bi{Pyl!W?>5A)6}^7k`cZwY68pX_c#E#u&Lm!lo9D?ir7-o-g~Vr#9GF85JL@rrSV_I#rzy zNtDmWhMtc6C|nT)vRqkqqBs^QRzd4XIN>+NvOhPm?2zOPb|~KZ$;Ag#6NF_fK((R? zON2l0Qz#36kc>{Ov!+Jw!9g=u>NS@pd8MM%TH4o0{gKGAU;`x*&_D`0)9A1N6yI%7 z%lM695D_k$-5#oLWU5(+H5#TKAli2u;1xWi7INqus~K-~_uG#4lug0=6TYS(R-10n z6cB2bi2QzE&Gk=$d9v4$8FDOE?++0Xy~vx&)XNEksLfWLh9F848hR_1z{B0 zRv9NJrP(%~;t;n_m_UIDJ*LVAD=w*$3~p$xrm{>(THk$Jl2h<65qzxcdnU&wU%|cY zxx|O4%~Ne*0x`(@Fdi%lAUK)PAfTA*Usa?i;Fc?&gUXj(D%dZBH#8WA82u5 zN?;D8`su~c>N(Y%>pp7#1aIZ zvTBxM9MWVaW5`o7t`Y3|AQD=6_d(YEQb*m&@v`}T;e5^Z@Y=TXp@}-v#FOQ@P4DGM zdXkJ(Lh0c!OX%an%W7X9pk--_9oL+<4%YsJ^}E!WFh4=!kxoP48~Lq$J{wS*c$${W z_NInl>h8+`TaeIFU^C0!i#lc#>J;O18xLqvWiOb;ozs&D3ylD$Po1;IR{0T2+xRFLV3K4q>+ z{CdvvTJ>f(M&fcgiBkvPa?*->Kk`Ep79E5FT6}L#y2lS`eG(ukH3w3SLew7z5^h6a z+G6C9mRz;@;$4TU7Yy_aKtzT{tsO)k!UqWXgXMq5eB+eE*!P_PQ)nnZB+~U&lYW*@ zjBN%rAHG^bz>ncRt}+9F-q3{#rIymWV4@JGf>0t_R6=A-*-Bn9s-v0E{bx?GfU`?p z!3IBKMI`KDhTm^cbjoblQaBwk$7?Y|)X2$S5iGvGE_|09^^-BkI{OgUw%Gw zd@Ey^^+HKD@G&Q}A#wklj-dpg0;0Y{)goqA3}*MPbGdmMU3GLT)hj7J9j}nMN{c=&04P?c(ZIus+ShKBf7pl zU-TAj9JN?pe;52au|c| zW5}c)Ce8w2C>={S#jfuW1H-4bQ%`|cmkUhJ4MGa3@WwOZVDWEZSfzk!ild51eS!_CaQHWYns z%A<5%p(Ff4n{A&5amXB1wRts@XD=xo@aul_9rI-475u#oICDQ$sZ zqpT~=WuL7jaAo-%c&B?#{H2~AHPQ*o-R*PRFVxr7-q|A~`K}}gO#ff7|ACs|%_Q>! z{8(qiDvdL(XCel0b#q7yzcb@|#Lu{&uJPqLUGY2Ixqta(kR7PgLZaGuJ)btzSArv0 zk{}_|iTsXiuJuc^(>)Qx-^hX$WNPV`_PT}XL-P_2NE;*_kX&^~1ka-{d=Md^Q!b8? zM$@nrc$(#-eWI}PIHjbz?P)T2&ThO$;CslJg^|xP{9^CZ(}LVjWbEbeDiHFTT=gF` zWn}tN$yI$P<2!=6aqt0rtxNKUBV#`B3$nfub)X(PMTr!ajWF#>i9YbJ$D-%3t z>@upey4LQ`iS>uSv%A>fPzh2=XHh>06OAoXu22@|&Ajz2&i|O2{JL19 zsB%LVt(8MN$xND+IQe9HH0G`N)79KvT*40dHfj~eumUQ<4bqv(dKva61$~e~S)vUx z{Ii+pN3tEnFN@f@3d7s$+m?ToW;L4QTjn&o{MfLZA1YQ|asW(Up|1U*=~j%bxlTeVV0M=X&RlAFSYcfzB+iO3X;!j!vV)JS4u3fHtL!lNU%j z7$&wR()#l!BE_OYj2uEend+;nO2sL^(IJ;|;NVFkmS0b(J{VVYMo9^3?&^%>V}qms zKPs-3w5z~&Lb(CnT#NVIC09BB;qFe>_h+3C>k2QEHI-@BFWo&bFnq-O*~>_hER--8 zBme9E#cv;vL;gPU|Bv#vR)#xu1~Eqm>KZkQH&gpMnXaMcwRBcL9QvLvt{lSF?*5q$ zT}**hWMQT^mh@p?bU0qhpw^g;td)M9W<>36Z(K|jDd=|kT6I< zCvrm0)LB^q_sxduCuQ=Aaj>=&|FOJgW8EM^Xa* zOd3lA~W6LcOdbw-&b; z)l>{?e#+yNKZK}3_?Vlr*`cUw?JTP3v$5SLl}0%r^)9SH~=W>p~5|kbw$Z z{5fF*ld1;5kH7K8O!ytwuZX>)P|q6Tz6q7)Fhsv=&&542O!I%e$OHs8BY?*Nso-Dxxw zPs>GOqDIBu4}Z6Y{AfDP^|Jp8`4|-F>)%cDTlu}&-UpVe{S5qyxvH99N}-5SUm%yt zog9k<`uUmpZP4}qVeBsg+6=cgP&9!6K?=dGg^*I5;!vbm@#5}K!>zazthg0-iWhg+ z;_mM5?tZfOxo3L+J<250^}XxSMX+66BhnOzS}%O%uD_Wzx6uCAun?e8qL?bgFGb7G zWlRGd+y72KF`<4`TTDKeJM7UY7_*9j^?d|;UkJK!8nxNY$wOmMdm)apBLD~Fw&0)q z3Vt}QY?OycwJHug4gVCsHg0r7VxJh@rJQ@b8g<8GuOLtpkUUYqij+RE?_m!8| z<@(PTT{)Hq(N|{A7yY|-IfKb!F}e<`V($Dy!Cv2LoDOJ&4T`2O?$5vJxwagYmfi;t z{9g}waOQ4$5Q(?M*a^#u?BiTxnVuG?SWGwxgx|6|~ouj47i*hyJliTvuLAprI#>mmeF`^yf zNu^;h#7|0;(#v&!ThQZ$17aVN2b>ho!t#6H0_(fbJu@**AT0=@x5!lwGEr&I9IqF= zzRTCs=rc(uanPscOe0jr;)n$>07H>DTQ#50a}I!FHF9_w#gHb<5?xYj@>hZWftE7^ zNbRUHAxbrFZ}E3#t6xc<63izpT%}~|r|KumTG415AOp}c%7N(f57_6o`Ps-EX+ObK zke}UyfG8<2j4BWZdwo8Kky!b4)3%*sh;Jy-7tX=?rMc{racag;o!6;hb%hVMCq-0e z?Ikb{VB>Q^-6+%eyClyfnL88k}S4T_^zKUT7NR{^7t%vE;yAAZ<~;A=|# zbpDwZ1#SOVtl`>}oW>!xEorrF*p25X-kag!-4_ z_t4`ROjdjnzZ$|tubK6|sE#s40PrS)b6F?*_VJ6i*Xb}p>!UMTp4@u+n;Q4~Dv{<( z@Q+vG6o09lqyMGFNS!0~lO(7rhT<2^yqkpjXVag@u)b!u&umZn^GbwP_&2f`u;RSm zg{3zJ$0WMTx2Ha8{ms{*slBxi&dJpwKi0^yFQRR0v}5@@n)l{zua{wO&sUA=}hUMolohCGQ3N5EgdK!MAWj|U^^$&XqM(b6l9R%ySv2eSPH zm0K^%P9j8p;`&-yA<~Is#gx&ys(HyK_V~Wn=_Nxy^#zYZ7R2&Prg8Sot}vy4o8=50 z#J9Yxdk*d|pk?i~)^ju-PY+ZY+zeZx)v#cSdf&AEvbJ~o9{{^b5UvTq)AL#X6lasr z^P>CIQx~h9?Tv5xW0u>@$+MG8G9{|bRs|UVfv!yvlO=y4Z_>|N~h2{?v;+leP&!s z#NeUYC0pmYGptxK$c9349IoTkM*@JF$n}`<*{T&wnUXenzTH`aDg~*_AQu6|S%%y6 zuO!d`+6pGb+|^sbzQy7xm`D567Y?MI+~zQu-*Z<23v*8EZ|-d6+NU=cg6F45AJ-rI zECha^eZNN)MxzjZi{%rbyq0>=pB`Yr>8C7;mk`4aeJ32b%H-b6el-`J&HHf@{KaA> zg!49+=}j_U@?p6W9E={QY1i8=ZTEb7O5=kSBmFT0+`heBL!is-$fY2Bx{2I|1Oq2e z?lT#%^#YMj$R^$^VEDj{YPv4(dCQ6X+S;qpQCLm4xGRHTFe+!f1?4ouC2bjvoO&Zv z6=fPiqgO`aEyZgKGO{JxMhSz3(H$Zlo&xqY+%3h?qtkzjr^P*7*)P;SmJgXpDqMte z8Z;GVUs*NW^re^X^dKXd!p`}m5eIau^qU^0pU>BHYMU%kOWt$D5``6SlY&f!(|_uu z6aUdo-lM}3IvbOHxmNK<%R?QS&n(u~lm;k~EY<_nB}C0d=uO=k*6qEFi^q$Uvi|MC zlyaq1HREMlZ$ma_9JQZ{Ymq0+L;@mo5`5{SKzIjK^M-YTBLBvVJ(J!)Um_wxI0{TH z&ox~W-vY9wPQ_?$r|u{``&ztN7Wkc4Z^}85LD3n^sgshQuNfokt>HR6ug*oY{(76y zpN5b%^nSrZwF{wEQ4~?+Axfbwllc;Z{#%!-k3ja{Xb=(`kP46)L~WxYG6{W^wvejG zugp`7_{I|2@ed|0F9}kB$lbN3G&_4mbtRImMAG=ce{%*3dt$$5-PJ{YtUA=_9 z6_m-5GdQGC^le!7w}(XXp#=E27~=j`Z%}$XUH(4a1~KC5BCT^Imzk07Eg17&6Wb(z zafBPY6dN?b9xXH&O?3jUcXd27pTH&BES^hq*BWxaDOd~5HQw;RRq3Ce_#1g%CT%Jn zmhbwaozB*UBH_gcrNKf5S3Ca)JV)U7`#ik=AoS*w9|!3RmjDLNSHC_* ze{!N~b!Z*>)_ZYV=@u>*`XB64?BDeMo&esMqTFDj;)5rgx3}u+J9gY^{QFV?qVznz zf&FZ%_TDS^@Aiw>Dl-VH-RSAUqh|@xY8aA(5HH0DKzfVlFkFjpLZs0yQHF_-Gg|L9 zS=*iAqjn1cnHX3_(VqtE`r9tPoV(t`Fv|l%QQ-!T&hIJ0H!9f+))@O|Fq~oaYK}etOhhw}l>U{`JH)$@ua_2P+03N+yPAPnqR$yk zCQo(oSqguA%wfT>LeM;KV8WBDl;N`!oMO4bbP7xnSPyi0law^Fo z$MJW&U$qQ?1`qe#5;?A5u{lcc%~4LFy~*S1{qb*m21iRL-R7j(DR+fH8W@%F4_(3f zyE<*b`aIi-SDzXHTM~%ft##`SjPUTB>Cr+4uUf9bVc|h)s#dFi&qq2eC%N`7#fKa#Uv4*6;?|e-d^v$>0(5`h964~MPnXHH{l)sDjwx#w zF=It5h2K55xOO_bG4^M*a0g}CL8a-9(T5G(IJw|)YzQ4t1jyX3L2=x)eqD!gcg40R z(4Gx0%jsDE>+A2s$Vgr9El;wn4F})Z05rJih~Gu#n#cr9f~#l(5%4}Bm*9399_kIF z;mkqgsW!ZCM|GVnx%yFOX1n@vJIm+2q&HCP)rRk+)KI0^3l;^Lvy&$TA-b>vUM za@IkVe%!;#iE=LG1aN2!+GLvJvb%8Tf5cP{c?5zit`a>S>ZfvlyZe&ZPk1;MrY`_Z zZ!-Rbh?wI0>UaKOc^}x~-1=D`;qRR(>EC+P05n+3p7XKcAUrj&B+}^Ty(M4%blHjZ znfQy1i=mOz@vU>a7N*)b^G}u1>W^AR z^KNrLL!{=ow}kRFj9*wmjXu4O|LIbEs8$9iWG|d$Sv}$F0X}!a^uUDoYKrYfdoj`^ zU=NAv#8rIw=KYoV-SV-O2#6$5(`R;wB?&;&UH&;BjG7EW7frPy%_g<$f$sz`tTC|n z`U$WAB-P*u6MyC`L8Oh{Q~a?1vLI7*-YL(u^duaZMxk-(1`EWLZ(NK5@UM{*LnuXYQCrUc!b_E-T4&D*B|1~&`zygC zXrnz6!Ie)c>SH^gjXH<+9K^QKA4+3slB~$002anP(M()qj4m7R4zVLm{{G|Oij`E} z{OeZI-NawZ5v#wd#&gsGb8o&>W8}-LpHk2r4`!f|>P`tq^$cmX8S5L2-n5pFQc`{- z*YD7Z<6+zw(I^nqDfB*DtZK6no=v59#&N&CAmV0OO#}{=88gZSj^qbOSTU_8 zpV6B|2g{b|BxrmLQiK=C8Y5HY${AoSkd!o*qE&SOSYh=cf#ezHv=4&i;j5;cAmd;5 zbQp>yJzI~bHGQ<0AjSMbbP4u}hdH`>?i$4y^zS755>!>l0}OuQf%8NzuQL3MS)o z&g_|gQ+uA@sQm;^4jOuo8vFcB3g9gckgiZ2!p6pc5iM}19o9oQb5D!|C)N4Rh z0WViyH4ay|_F4QYnj9Fm)24qKqkiK~i9b|aOu6CWDgES<(jccix0yn`_9T8I%~IlM zRqA7fl2%oX#jtcUMuU3PdOfw5%e~aF@}FjVdqw85-JX z@N31joGiKG;LfWOsfu}&8?NWV8G=#}otJ-d`K#{#^8$oZrkR+g!yOt03^MhZ=vA*0 z&Etx#ErHg3>X@^xi46rw(Zy-Fkn3y5kkq~p$il^^mY96`{ixEJW0OSsd6FqO5o&yq z_5xgcHr?4VW*Qe!QV`1ue1@GumI(2eFK3jKra+Y#m%%qf-YTRj@ee zRh(DC!30v|3NRTT1t|0@;r)_0gz?KZ!~*$5TNps&|F!19-galYypZANl(s#$iEr`5 z`E6fs@ecYyXCd{gWt}&=g+X+x#sQx+n2qL~y+mYvpqr`wrNm#H;?uE}ITx-pZ)jiy zSyctoauO*~g>lH%#aPx&KMQ`Vo}Uf9m5UDWJRy9hJsbEkX zj$LhiFo-1~l7qan(7#ogjEUZY-JWwgT^fGuMVH(=9LA6Qv9Z=SmPeDBIcbAyFuQFR z;jH>sc7V}XkWE?VBIe}CbacW>+M!v3M1<*$-~K(Dm5eO~xy5m1o!B#{`#9!|{G`Hf zj{xi~`s0hjjG_x_{HEq$s(^>?S|twcx&MZ=bK&cSY6XwaS|)U_xL##nexhIS0|$5e z{}V<_$OZBc&T>J~q2iI#U+QGGs*i8Zc%R&iSoBloia7Am&m~f-E1jMjdL?ZO8@+HudertOs&DA^&G_7rPRDn} zUEBJK5~~#ZpWkn6a|YOgq;_2#U8Wf58t{!wEOee7AubB^9$|rK8mXs&CK+<)OVWIg z`F^KuZjHMmjbf1Q3zC@kaeR%&ZgUJKFJ&X&6zAO^y4X#eO0tTrkF)NINva~`8?Ea; z>{x|gjQ=!9Nft*cuytttJKz;VZCVo3;DU5p4KjE78P&2^uvX(uD6cSp4%u}91n(C|2mwPBE_^G_BB-+ zB&NT4LYM(7NA6c2r|);Rd21|D-!%qS8ay@y3W<#P_P)12{G^C2_L@5+-Gh_i>B(>O zCOsYzibHjg{%>i2=6_53heP_DwtV*#%q&~-UbJ-kcyFrBJgz4!EAI;+Af$J;KOWHq zB7_=G2@%#lWN)4xn9s51LmdYo`8FEqsrVne=-aLNJCcx z5J}qUQwWk9yVa_)CpmxlB~SPpmx_a>J8i)_4$y{Vf^5h%Pp@6 zFJ8fkfrF$}uO6GBk10x2hxx+snW;pkXdmb6Flk440xk{BCQ-#!=?6#{5{#@aMabYy9g z#?3ioV*P(I&(~5Q4{%+hVK+X9dNMD*GJd~CQwI7BRD{bT7AatoY7(3Mzv_3Y1E_~g zoV+H^+0w#k02d4b(zk2?Mjsghx+w@u3gD+QrX||$W?Lf>gt|Qsapi-jy~=RJ&;%c@ zy}n~TP@q7X`2ad#T^!25|26K%`Ht*+CxKXw|90eV(^<#?oWm^g!$&3`3ghXtLCI6a zp$WU?C568vCe)}>SSsJ7MWHo$Tx@yfOW`;(g&jg;``aA#q+a@BNZC55DEJj;)bv)% zueE?l^Y>R{Yciq`nrxORJNSC}Q%Q zc>U{~gJiEsxch01?ojJ)>VuE;c=DjxO~D4LQc2a_pSkB^Awd$klM#h&03j zg5ssBdZ@r)%w6jd-QvF&35>=rU?3DrSnuaE+Nf6h)*&AgN-w0kz;x)j!1JPZ!vT^a zur5NV8caY<2ekja>4cWGB!nOZ5Z&-=0}=eMd8W>d56&N72+v+9-K>es=W3Rno?5Lr zE47Y}3rqPNk`5Mb=fjUW+k-;cG{u0D>r^D(%sz_Lik--~F0203cz6QPNTlDmP^rk@ zr#_$FVty|&r=7Je`Dy3TxOiMObu>RTUzj>%B1o~V+vqqo=U`C=bK0PlJE}G==GuAv zt(a@uq*3=y@YfVc#QHPe zxi;4PZQ2D(&fm;Yq?3Dl!k3R+ZaSA~CJ?Goim_s0QJFy4t|kTzx8w)l`j1wWcS-of zvxih>A$zo>b{x4u3=$P-dJVIuManc&Q|Y5|5*@JBpO{lXuqS@fx9nVIM@WVK04;4hv|AHMP@Y}?F#)dI3%tRkQ5G>+z=B#fq& zLfU4pFadnYJ`-I3CSFzT?HJus#C`lnMkDQ57b&3qQYIw{C)L6%PBzO z{Z3TWZ^4;_u@{X@3~-}^C2Ry1moKW$zv~lKGQ}bwZxpIy&1$k#ApZ1sq3EN|g~=dY z04g=o5Y|soHO!xtgg6maBi$Q192(QeO~u1wTgu2US^{Ci74$q6hmV&?e=E&Klq3y}g$&*J8Zn> zYMV0Uqu1k#`qchj?D>wPTWny<<6KZOfomVzb=L@ZUAVLPc1}(BVWqU?czU)7Z7rt-7ue{azR0|+1PX&E`_d)$OliG5pT2YK}Q2Vf2hss{Pfl`kBAhPCrAE4+5o_q8p`-Y>wTT5>Y_?5_f)P+kq+UPJJVC<`~0XpA6_4B)mqtfSqKwHLICDry^L%}}`K+ATqOw4is7a#S?n0n$zWz#C8Y|PH1%3IOo0f+f zq@An2(=ZSnQcj)eR?Yz_jH@n2_gU3BNOF)6^GY$Y~W2cv9LriNw}a(Ne87+W7r zf1YC6M$UP~tgzguFn_Y`uawJFR)Cesp!88Fp#Rli72x3YY3TjkYYWcdRu3PZm9pC@ zgHl`pMV>b2HpSr6E9+Y4jg~IN6*%Vu5ma+@%8%Hy3o5s3l!HI(dcegQRxpZXE|OOy zt+xk2`y15t2B0^6V>9v5G6035GNyC~d_@KisPF@eG+KS3Z`&l(#*bMq0Th6X zz}mPmG@2-W(2POlN^ND;w8LlNI?h$upiM1u9my{$c2Aor>kYBC>`+m^(vQ@rG5kb> z_IFfhpq6k$8VEjjC80lwG;v&{P8?lQXaQB^_T|?}3YK0h4$_!l2oTY-FLqTSzToVS zN=ZNOGQD3p5-d`mEa%Db4PRh^TnPvJZSulct?%!%Dy?B+q@ZTr#m|vU;~uPkSst&s z-D@$tHIr^JT48B%F!!20zn0eH7kInqYIatArrJsZpC@F8YW*_nt z^{ms>54MOytL5o0XmIr&R{A?1<=IGHCWn`c|5Z=L&l_!&z79c1lIE1H+kF4iydypd z&LY2s@q>g?n&h9|t0f$(NAC&%1+m<79ZsIBw0Ul|h+etNh;{sF&?#!+b7fI3>fGG&RF8CH|PFCvQvFx(CXPjf=bLJ#;wOy zZBjUA5h-``!{z)~FZmnKNQ^S+m!p`fFv)~s=`apD^L9RDvy4RM_8cF6oi^dq>ra@t z84gHP?e4hk!HPtoeF?arNT~D8+ki3nX>doRkz)_aoDA8gk(z_<9)m zXoo;BCcEay;BlQ=^q-E%H@0R`0c1IoB$2+@Kt7%_brEx<1Nq)V^WUjFy{WUIP?NY< znMCfd3P70t z+U_dfWuP~(W^?#LdmkIp0x@B7!dGiS-N%}$;215$kxGwc@trlmk_A+c;;X^=p@a4&(Z30s&hTY zy=~pa57H_fDL#7phh?7{w3D<&V$sGk2iwCCq`eSdgJmgw(wnWM_b}z+_!W!f`}nXS z37NgdnJ{v=QI4kx=SPH+o7yq=_&CQSzIo4ex?$(B^w@gL`@cN$h@rpzCi~y1cXwA7 zIgH*)pO>xb@;&o_U zBd5#l1voS_`#~B`w})^U z0TO0_fV{i77C)nptGf| z2)5{1>Pyv=uZR|Ud!_M^IU#vg@Q9AoU!jO|yhKjyQd0ZL$ny)g3&4`V)MxbYd-X<= zBW?O2k7FIanpK9K&k%4R)kd=#v8$iJcfDtk*1bnj{mjDdA4#VA0xle{FVX9b>IwTj z(Mkvrjz*qZt0gkrC_Ff~(xs`mn`@mA-3|6l?AU~3dHePzdbZY|*GXQsHpVYOeN5u& z30xiRj~$XZ^gYSD=IF(e7Sr#7F5GUeM=bv=8s-({@z4@)4co|X7CIgUD_TMdVy_+4 zx>w;OP$g)jJjOSqa-@We&@etq&h}~$IrgVu*G89&nIF`7S?^!H>C zpK+pW0$lpb3-~S(@>Zi%x5mqBmebsLCU3-X(Maju$TG{CkRCrsYX2@YARz00G`K|7 ze0z9!=a&~;_lmWDB^w>A%P7+))hdy@5Bys#`BE+Bk*M$G1n8;qU%i^Gt91=qnNW!ryl;0w; z#U{bzO!cU$at$2>@T?@?7m9uWW19z00O@3cZHE#WYBPlsC*JdKfpQyHAt)e<8%y6PkNS=kBI>r5G-Qpd+99(7gLy2)rzcv^7u^!a z^r5y_pI~I-!~aHKv9O%`C*Sk;XG{v=US?vr)<-vB(AAV4II0*RA5Bj@d!C63JrRJ9vFBy>v8Cc< z%3Oxs{EyZ&E(`x05v_94|4epZj zQs385;^eD!F9Cj+N1t8e8KL&7g(z9l|?1Mi0ae@;TiDS2gg%XwBo@x`T&E z3^e{~N1l9`n$Qh{a;m0IK%==DP~; zg;AdJKJjS{*HT<{VI^M@l&_x$AXQ79fytVW%z615zO9yxUjDU!j_ z`u)NbmLqGk;kPwza&xqfIFVFY86+{PAmA9!QeJd5gdR^FiuZR!!ImSX$U`S!R-LAy zX0+p{$@Gv-IbNk!S5(NB=3K?7R=WlJE>l)6#*YOFE;`e&XJ1;e&7+Ja=aZ%L$FaQ* z$Lh4QigG=JnDzPbnS)HNwD3T>KxYH_^B>LXNMkfr0^!R?*w)R2>Uk%g5fz_Qju*{! z?aFnANq3!C@8gItc>e0&K$J2BI`P;&Yhs3Euxttb zV9GX=BEq!Vhtt9Puqu9ryIYLCM}Exor_hYtcegLLx$`tb>4ZXn?&P>gWoa|{guc?J zPxo&h=T6ivPxXIIqd%_^>-TvTT;@GBg%lxf>3r1a{n{jc1S(r5OZ1O&1lt@KFm9(R! z4pU_R6|(R4h>P$2Q1o%u_;_Y{@k5#BTTb|{t5Q^~^2uz|Bb#~yqPrI2;bC`Rd@Z=G zMyiS!e}fjHIU@a1j5LiOqtCAwl zsc_Yw3*5E+@Mh8L;o-S?&H2PQ;qIc8KQZvO=C9}R7F2ZaVNHCY^_ z2c~Xb{(hu)&Uu!G%hKYzy|g!%PbUH4cm9aH%#$Xv4esNiz02m?S22C<+&FX2wNr_| zh5?rFRrr-Znt(57TZ7w8W`s#RxoQvPub~T^;eY3s38E$jJO=4)J)qHrS}W|Hjh{ex zCO931qRYbit7N0BOtjA6&BnRC8G&#o>#sj{7hit#S8j>>&SgcA6)$D^rmovtWOKQx z6iRHYs>kxV9_*%o;dEwtTBrm+4no?uVHBVhY*Cey&Q%Vis`mk7*iPL2+vMP+-TmDH z!k(J#fk0+lDRVk=Q@dvirj%SHg>WWSRVDHjP<&m8f&iL3gxP{l_+D#Hk} zx5ghyPm$k=5KP(5TC%l2D5gn1MA5_IUe~ip_7Ap+UKq+a)&N7=q3{JxsryIjx zChQV* zG$;o9f?R@=Pfd`GWm{LKe?Mo-=d^LB)~>47!giU{oKnu);lwcIILiljs*W*ogR3hu zymxeJ+EHuJ42MB1s>CAk1F1aWQmw0f3b$8Om3b^9|kT6$PK@*cdtQT=Qw zZh718l^i=~yltN23hR&IUa_uh#}Pf9e7G)B;Im_iz^JjZWclk@dcZXnp(f%c?)uvldl^o&84Nje-u{I-ZR7Hbrd5_{C~U<*OB$}wnuXa+l! z6PK7Wt&+PwKjn{{)3lDowg#c>P8;9=TX7Sh+FvDN09% z6L~5w`X4^r;YW{>#b3LDF(r!E=OiBVxN%Y+g6V=Xr3^LcJ7~Ve#v^zSxlrZ$yP)&r z*x+(6H@~rAg~im7mb0Ob)URA~^cuz^#y=LS)E5S$xRo*`FPVeDvzwV={+(@OJdwLp zz<<-f938j~qsu$XkaJ?IV#AlsW8=rL9plDosSP8+)M8K&MoY9@V&(wH-{g!Ti@1|w zh2fL$9d8_`jChh?Tf|fo6gaFUZ7KR$*jtk7afru6nI}cPk>~En>QKA%8M-?&v2m_b zHLEfu%6mIA*n`D5wSL=D-FqmkvgG5ZRlUQg-0^$RM#=)q1RUdplOd@^%ZF!(`-S7z z7+h4CO))=?VxmrLLW~u+<*B8^?Cq=tobqlB39&7dX=CndLvhPU*9POukVC#2Dq=Hd zvfGeHjDC>HStWYagqD<1rq4Dn{;De!;=QAweG8Mc;^U2mnj{4(E%W*$JNVt;(nidH z{kz(?LFvs0KkYLjjYAvo+|PK(Qob}{Gn96SZ#Y_cuFNEdaBL)PO@`W0nRk^3O-}Zc zz=Dv@kYK26Up|&9sR0>ypyu}y9WBYUBe~qzG zN*xuy%_KW~?Kc|NK7~zH=lIc>J5DduEVFz}`^>%EBE=53d9Y58=AkW*m4m*x%*$DG zvChd!fFvSRDd}LU!RmlUx6j5=KO54PDsa~rDMBx!*_eA@AuJ!uT`Tw}oR^FH!8nZh z*nhVb|64wYW!hd>@7%ThqJd#|U~M@5$LQxzzw;ZPiADEnFy?238^4;o+=_c&o)4dE zlU|yPQ28)k(O@-X^-Caa` zD*SKjL? z&g&zBbM$gPF|&tlUDwU@r7vBJJ|Auk%ljSr4qmAu(Fn^s7S-jmu@m2% zj8N*EImt!WyZm^;SioegjCc^7N(nu~Qt)=ru|;8-`SKr3N>i9ZJEGBb%PTqMyix zVWUhsMd_Za>JhCDOjrAUjh~+Nou$nhTrNx$u`xnC<Om zKk8@IZ`-Aaw`|aOz2~lX;M=jsFvDP@v~RPqT~|zcRgq(x>BC$h1xTu{J=m#a+lwk3 z-sylO={AkL{}d#gP8^!ryvX}S29PD2J7}{%XsFAmGM!7J-r3Y}GdwnPEz$K0KqvmQ zN=UP0r%=GTtiqr81ky}P12)HGN3~!_m&=*yp$vDgo&*J1eH>ZXI;0`jNywyDCW9%} zcZut>gmVE2%kiQD=_v4!eeA^6>3_eA{%a;!+u>MG61^TJl~OZMiA(KVs}-i#oCK1(Wgwax2F?k2 zN*XHD3{no@1o(qwWC5?;hz^a+(eMi@k=C-y{*ern8C_g_6ZnP$gdv=m#YEz0s3;kx zPHOSG10}=CI~N6l#0gY;V{_fqjv6Yhxn}oZz9^tff=vQiwIDi;wXV|Kb_-jWl$f|> z8lb({72TM&lS7HkPBg3*`<8`U+9{4lrMUCsn}^b$D9j0f*6HJ>%Q#c>L^n(o+Rt!ia1XbUm4+GwKTb+ zgxZYdHXed#Lm(vxTvC?SLBNmR3=ND-jm`-T*$MOR<~QUnC)~+XT|%g*%$5~sh&Ywi zq8R5`_jBiQdn#pr$eKnxG40L*Zc>QpSBt)ZJ5}(4@Fqf**sp8U-WxbK&Mw&`MJEWVix(;{ z_Q9yBV2oy^vf5H`{rg-$rTvp0?zmx`bS!(=>{csTijl#hM*?>tzubtvdlSh%_$!dG zoLy1txZ*53EU?=;>Ff1cR?ydj^VFyrGB8q|T*y`Q4foZA6J>jC^3k1Fgf50`H(86* z&T)b;7FZ3*W9{+}Jq;A>W6tYz;nHmn5eZmE*WFOmens5zFtQyI-R!$p@SU(|Y}0!A zHUHT7dmtp>Oaxb}90D&IJvz6KV@VfGYZ!9JC?g7rT;*R-t2t^vT39#rhNUJc+(msx-fyu9D@;y=T?CmZ&^aJci+qCFjXhw!=A}I%ZLwLkW zjOi29O_5^%t(|XA1DuAY6c+WWNVTwnUF-x?1&f@H5Ldvz=0~l-Q12#C)c*YVfk#j8 z)!ZxxQpzNu+w}K-Z@0TBYKqDs zk|KG4Bn>sOjQWAHzlG;&9k|vBWhB@x1i!b1lPZzugOuQE9Upix6Ik9R&9{?u>+BQU zSkueWVC8^^F~id(-8YuF)%kf2jB3gf=Y(j6GYwc+7n>iB96ypv1|!Fk2G5J(qBg42 zugj-X|2ud0g@R)DtUO)ORa1KQ`*?flb{B<_fJF(_`^hnpB)SB|)Jz8wdimC|(E*ia zc4rbwL_4rwz1S9w0_1g9qWGc+S4!~rgoExlE+K_lXY!G{sa1mPHJSf_;r-mlZv{1}-1oX+AmQo=`Ei}YRN znc$MXCVq2dwl7_WIR-S&!->eaFb3Ku;VCI$=Xr@FKN`?LAN+oz%}l=3m24Xjpks^q z(J_@qnVRq$(d<>x;YEslV;|SfDk-27-c`<__AshY*-U_4MbvH_Rh1rV#-GsX&&n^< zFR!fhSuZv4F5Z{w068V1j=llQLOXkm58ieqwUHT$7jb1&CD^WNB6psKAaPULO95_VM~YJp7c z3bvGx)1>q(<6HM0cFrJl%%(e5h>84uswADojv{Jbeky)+^f>KSWFHBUhN75q{H_UV zncH=JZUUFo4DAc}hPeH?MF;;~LnG<}~&Y{g4{zA4-VVc?eew|U6nT7L6N zRkerYRm`t`Tic;rNYJ5f&L=^k$aeQS4&0|aiHO`2EN)jX7!&RX!B?}XtklTW5Gm}* zFheCqrgt4#j-gIZKyDJG@@VALV8flCQpRq2d&h(i>=>6^pWp zcQc7LH!gEUlxi_b12T^%@iKL+)oF$DEYEaY*zR`{r^X!2k#UcV?p8}lbRM1cm|q-q zN?TE)0AKfCn1lhi(NY=;MEf#>)Kz){wXpo&8dz9Mlq}5e2%lJ_&rC9JV~x+{;SD9N<1iz}JZQ=8LnG<3L#*lI*hFbE-)3D$U@kRv(22vSjc*g-n#CS;?yz%}Y#@_NT>Mv~99y%n3ZWx9Xkd%~WNNE{Lx~02e zXody>rCYj@?(UYBP>}9!HuwEJ`}O|4ntxzE>$}!@9@lYkAxD0gmH4G_N8GK2sLy@= z)oCdX1qk8lBV{%na~%8#heS52>%GXw#-l?dIRf2j{ANrbA1Kh2B>1$2hQdj1HyY4= zz_Xk>vI&{0gle?++$oG1F^CpYRs22$39=C=Z_PdXDpD=#`{eT7jXPOkS>LVBiKP6l zTn{JGe>Yx)eu>q3C|oS-umARw0qmS)&UMQ-S{NQgY7(7bqA3ez=;rl`ex~H&Yhi9D zQywgE8}o?GD$9$m+hlrEzkZxMK^@v~Olh;ezrjNAcL3t&KP1KCvHIn%*IDm3wH4O8 zV7QY%-sxq;;KbtJl@mb-9-&}vB?1^X3N?G;+wJ2i*~Bj##4n@*TQi^=A`^5Vtrdz@ zz7cj{>gnO4u|s%GV_CH}W}mcGucv`d#sIz&7vPiO%>w|`hC7=R4|fQ@W&vAdh$yTXzyh-#eIAB6>8oA1ynzq;=49rHc98!ly7 zlapXQL2Tpt5$?L1@(NA5{uc7pHWv#tf*#d*QTvYNv20jYj2bdnCADZnTxkm{(w870 zh*k|G8srM${Y-lg;9(aJMQ96nFXck>gO@x=ZZW{TS8WMRr(Hc95_tY61}MoBIe{yM zB_;A3r9|<3IDzY5UwGm6zdWjFj|;aU?uycu7o1NtwA;sYG^U4Nzf02lArjzA&`YZo z2R|YC_&&Cw2JZDQgruanSu8c$K@L0Kfgwf#dA1c#-{&U`{80MsGcPN>Uo(qN)2L}n zJI!ZwJnTwCrrS(s&bzpZcd(M>u@`&vV?E>q4EmWb_4lUiw-*fT3q&xWTqxqMvu|4PCbY7)*!b!lpP+E=3$LIyhT`1Z6h@AhJ zamvR3PsZ5^dwlgyWNSYo=h&}4RC>tF26s-B`(Gw16H5uKmG8hDoSd$c4T?2hV^kIn zYg3NV?Diy=e@;w3VXthZLE$02+;XV^2VpYF`NV5)n(lQ_Ra52~2?Qx1BS)|W)Oy`< zP7cB%h+z8!gH*jvpDO&j>(d88K;*V}a07n({gLdNmv`3-q$q^V1Uk~JN7z6npH{|f zMcKJS6PN4DrL+gfVi!W_0|ueyh>F~l-E^GcW7N3(A87qiE%o82nk(jyz&a-F}sdC~`QDXHPb+LngmK|Rt#_gIq z7|fb^p%*OAd3D={DB;vLytH8eP1k=VK93U7&g^T7v_{mf<_BSsDOsq$kNM@JKB&C^ z1`i$YFOtb=JacAFIhYgGRusTJKI3gsA%#Bi^~e4E0?hP9MNwHMyR*C0EvQP=`qXA_ z$D%sKoo~`@aX7Cmc_QrH=a18^HPeMNIuhOWkUpbv@t;$@X9_#P%@dnE6Of zPVVj>?~EO<0+fgq{7zQqMIPFC6RQU2Li-B&CMK_gYzR$wW@h!0!eLTb+Yhan=E|If zD|$e^a>Q4@xsD(X&4c&&_j}J1y71RkcA>l>;ka1mq}7&_U5Z910!%|}y@Z(aoVN2y z7iSStYRp?Gn~vG43yA#z%rQ4*wDX*B@+nAlbI=6g&$$5O%Q7?w0wJI*a12wDVguOS zEbYe^?t)W|%EAOhznXQ4#%0oG|LpihT#z<{UzM#%Oxx6>^mMC4>Kk6ifnC%lLEJ@D zz@3b=CEyF58&~veukjMmfD=QJSi&Te{$IH*&fG~4S-i#aRmoilOF_$4|dp6 zf`41bcsGQl5^v1pQM8HMMg4%}00D$sbYBdcZO?93<@wfh@ZL@{GF9ho=yx+B(F3E2 zY6U~!Nqp*6#QjG6hM&HD8Gpi`W}O6sS7%lkI9h`k-2$hSQHe}2d>(w3_V&IInY{c1 z!RK|A>?!{VO&;z&(3G1H?pcra#M{%N1^T0rX)s5k)A7wcmQ@<~@vt(9nb|%E?;d}q zk)pVu%O8HucD8$}o4fxDBS}EronV-WDEkG?ZGFIEzJ|TqaO1XGK=z{z#&`SkWxrws z9cVa`10ax#aP=U=$EV#Jm}!rF2sUh&HPlaUWhfb~nX#zz)U^Bda_8A{v-;2Ryo#%= z_h3K?;y@BSy#DlS=jHIFzRB~MKg<6%#$mJHPjq9GSGBoTrSh;^T!G5Ba^rY4gl~CnHO)ct!y|wXG9|!+Qm^K#U3ksf?@9Hr9KxxUs%f;Ts z;ETR~MfS~WxjeUI3Q!j}yr)-X^1(*|<3N6{7QBeOKDXuu{p5~nhhH1dw~C(+ zY7%{$NHlaH+Mrj&y46p?rtWj>_4C(pv==^}qfYnVVCafQr)rgj7){=1i4a=9xueZZ zVsF|2%z{MCy~s<2KCs`OtB25Z;vYE-t|XI`TGczxyn|BbzfuJT#rw(gBv+GhZ*soJ z6(vTryWGsf;f5`IdEXhP06mFO<7T3ri>Bt>0YU6x1wV=AQ9&k#9CZ!LSUQ$twh?fI znThB~C6Uj@PrK=pCiU8#_Q(ElKtPMz!M3C7H(~%e!W(b}@j-0~A7hgcCHAk-JZ8uS zv+rOa4h2Gzu{NUf*PFSuEe*!RF@k>Ye*DkGA2ezx@l%=!dQ+s4i#7X;Gbcx;G)(PW z95n+LU5_cQGNt}STWLYs$?EqHhxUpb8XiRphv_v{k}q4WH+XjbP{d(>{b z^@K&JM;Z5fW!BG;>@tDqV*}n6#0WxvG?1rx!{EW}BSJsj5>(vDnbW0d!hzF_94ou+ zU`?eu(KU~QH&QXS%)zf82vsYdtw7D?{YTCW3)r)YObcw#$V1B%CQH{Cy$AVIfkr%! zzvgS?R9(hJ$$7k9@9AkM^|r_Q9XfRi2iTtat=YG3#guU*drE7?!QU7^D#UHVE`mrA zNJ!sUo)%DTAc+Oe3Z?-Tg;!fou~R+fp^}7LyJGypre1v0<|J#}9BDV6ooGDwgQsEkN_8@PEU0Pgh^zK#~j zYIZT)S@TiOKCV3WJ{;6NxY>+rFKbm<7qyHQQRcStli`IHwUk~PKz*v*UhWR#Mg%&~ zuNRq2EV#mquu5u>ccOJ|1STuem8qgeCf4lz9S=0yVLR@2qdlY+<*_P4cuU^dk$*JQ zcc-?I9kNBlPO{UGWN?#{fKuxnM3OIFd`r=(*-*QNfkg)=uct}Q>6)7(v>oytO>as@ z2zB9s%N;>WraqT@7RS-(={BuZWRwt33<=BBw8VPLuD6re#KI<_@1394z$BQF7CxGKlL@zZU#9IWOax_4WN^Ien9TwCo1ktE()Fo8gViuA%vFH=u-D zZ>Ho|ZXD+Ms63MW8R0VZO6B1Euzx}Hx>rZ@@dIetXX5(T%@GHCEX_+rhr@zt_hGHo zeeS~MSHNpZDhSV!+T)2eDKH@f%L;0QcbdkFAz)3$xe4pN7i~N*!aCn+CKejWMh+On z+^z1E!cM|Sf+l8)ZP)%q10+q7HQshSpy|8ZzfIsIHRC3ht|H^N8*ED!3t!6s#B-4s zDFD^c@mSHhGnHd#B{9Cnf*=LD-`!8@wYF8(JTD;pN&;1|nLGE&WHE%CQk$EesGC=) ze5#B{6~VF1{#@3foon3E=fuoh1nK;fEME1W3Lv66~9hN`wpoOEvJ(j>+~th_=>!1RC~OG#ZuX+6{C-!nU6u)hH#xxT_pY8%{f)_~UN= zncwndOW%fj(CS0CHQntwU9iUin%~8(6-#>TszJrtd(H3TY<&cTzIDMt1t%XrYaAFG zYr2j~W5o2ZBds9T=p3=H`$Vf!UIv`&_HNsfwz z^u3EgG4S31qHrSL<}hOhF`pK&o@pljQA^DK^yV%4Ji_>wE(<$agjZ#!x%~|1|78J$ zF9n+3{9Yt07}_N=l8#0|M@Th=lOU_f(HI?2>ItZBhegm2@#$c}8YFbI%R8Ns%{K~d z&St1&PKYM(Mei%f);vELH50eptA}||d%wSnHd`XK^k^$%Ot51-be1)n;vX&1|5qcF z!Zy<0{;k98Gq$dp3^;FtIft7>n>CZEkF;1&&k@$ry>-<(9WC zhoK7fKmS>U?Q#yA*W%6825ZzSjT92?gj2XbuQbNwX7RA*6VP6424F>>5Q-3uKL0Sr z*DIfIQ=))OUDR~2qdj96PB2CKP&a;lTBK*t8BdZZHa51P@Hpnm!@>0OZFI!Yf!|VW z?PmP5Y7D6Gk24~nMBjT0W%)1VnfrY7F|5!jw;IwWQ~A9&&v9(5qV;ti7Z3WHzPOb-QLmd&>cn6- zp$_-m!7Ch3vJQTGS}!uE`f<7FZ>fI*{U-sToFwWNlpw;iy)!}__ zlL$NnIfNXfK)42*ssBs&5jNKgA^PjD*N0DQMTFBWl^NWi+? z>v9dv?VAd2*^)$2w0c;KW2bIX$LECs;(fiPUeZ%g1$dwsv_IK#-XA08|FX(8djBx+ zJWi23bNcTJ%a%&PqVI0P>H!zBTMnHt^o))q4UuuYv=QDD~(U} z+iQj3D_yRY3}xl8l(#^lTs!W)2Yh-#K?^V#D(>fi4k*Ow)P?oH{skvn)X)(KyHylz zhVEPN1xAuiQ09brekH)vTsaDvvg6*21VG`Qg9BcBe4)eKXz{>=;y!f@zOas8b7X{h z3XzMI7rU*qzTTS<$?toS`Ik=;NzfyEts&gP-_%(`5M5zzw7H!QPd#_P@U=H1L2Cb^ z^UQpY%_1ACaT9d{(7EPS|8$R`1d|&$MU7gRnCbu z%F8pvNXr7&;=2=1S9!bI;z>d1gNIPR5so1Qfa);aL--&+4+8v&x_$(&R2XBTS%e|N z)pFE;6u55UQg{j>C11{#vE!D;#35%re&ImEgBT+rV_V(sAWL+K?&+>yOUjV+rCQNX z$+0mm4JnSD2IG1nC;Z_j3l}RicM9RS$Ff&0JYzn{yVXyXMfOYasC~8`;lJBVKK(;a zr#3qj=$+|jqalS$sU^PIc6ad2!_;)VvkreV-1I$R3Y*4KPPGk=JicMtz8qhHB6P{u-#b0lLShKz! z3k`NFGpeg0h<$xnP-s9zQm!d^lKjAA(JP6nZKz4U&42ZDpE+gstY9$l9KpsRhLHES z#VaJ{Zri%$fu@!7PAq+H_=OE$1xl+3f>N=LgF z;W+P14+CSDiz8W3u?=$-HqH0~-_W{#h;vwQ>^T4ZDcgJ8 z<-gujg#K8ozDtnvwQE)uZ`0js)4OkD^ItxCs_?05_kH;h_iU-7_S6b--PEBVh!{+t zTQU?B@;!m=`L$9;H(pG(DTlN%!*HZkx}{fnV&mxW;%<63|Hzz;JPZUe|M_a-DGh+; zsnvC#o?OiAFvE1Aq{XBtw%?LDG-jVVH){VrL|C1dJC%(%EwH_~w+cQbSs&(%OsP%X zoi-%{7^rV_v^03%8v|ixB`DL07IYcY-Xf z7v$F&%+C9f(GSuID`kkg|1ho4HXx}BWkW~SZX2!Rc8RT`m&SPtb^dM*NT5b`rcW9o z6ij2=k5S*Jj4y68O<%VDtf*p7-cxrHA08fk`@oO0FAk9yyv_;w;@AbxITW`AXrjLr zub2`6ckI0$>VfTVf2H1-Scq9Il#|Pi=+A>q%`Irbz&c2cg`fHu1Ljp(qU623O6isV zsNtR5`va=l{UPoI9?pq?7zD1s3WU$76lmZs<)~-0ai$Z$^+x%QPD@~rNi#kr2YBtF zbDiyg#NoECw_n(vkDwtVp)OjyT!gg!E1$v)e!u41_dzj@XXTSmU%vOx@oOrt3x^Fe4RD{WXt?m(w$2R++Xwz3@? zaNqSM^QS)Y9CC39ID48BRr4(DAQS5 zP+VGWqAXQ-T9U8KOG<8)wYp+%xuOb4;X$?3gwnMzS@Lz((J)nY5S~AYV2lqm1;715 z!bO^b%!zFc#&-ME2lydSz=VS0B~-Umu=hPGh|sJowU(B_0_-?BfC@p73~oG$ zPVx0DTY1b(%$F4-FokQ4WKSlG1=^imv>}s+@4U7Dm`wu48e}~o01|?J7>jWZ%x8TS zLmAmYT980pJLL~FTv^T(^U#d^hUoaw>+jw}>QCYIUo-L##d z(uxUrBF>$V`cwn6EO#F(ROYi=5`-2M0N*;!T&b@QCgo?5RDf^>cw;eqH11NebaU}t zG%6Dp4gS#RFejY=v!Y(Z%mJ5XMYQ}8MJz5d|K4C$guVBUeE$V4a#7qC@DlKmxBa&d$${qKEoS#OU zI>$LhD8E6#WGBX}c8yBbFUxBp>X{;nY3X2gx17ONGqMoM_5o>WsXMyP`pTwLXTPEq z+dOpu2SoFlBcaektY|=f0r#Bn7%(!Fm<$|ZOXkRsDxBD~um7-1*b-SWn+cSl=R&uX zzWj@Q=Po&)Fkafl{$`Aw1u?>Nfj=wd9VEZl%5hd6t`@z{c4OM;#5g(u*ICk~O~U|L z;;WQ>hVB@MSTR=pKD;q#L8)u~zG+E)bThiT5+{0-%(14&$27-?Yg7fQLazvSvfw-# zAPY$W*mR9?THH!CYQk}iP>t9NxiLaE0!cBdF$JX8Jwr&lRFS785QqaI5+2L1oA->` zHLAIPGF&=j_4r7SIWI0FsDb=FMYtr)(D|%sfDZrxNo_vI++NlX?~YgbcD*8$#hSXH&rF1-I!&eM<&Q(~t4>Jp;h}0_d(ivdHIo zoks4TF-AC+bQhl9k?Me)R33=1Ts$}_a3gm)3W6$a9v?f%jjm_}Ee3YSo5+2^IRKR4 z2PdKWsXLA9DGIp@AQW32rp=vAdVPoSaagR|l>6=7FNIovCwVD#YJ8DfsPu2MnGlW2 zU1URs;~Wqt#(sLJCg5(+Z5&`kC!sQf+Ul!N6;bBZ+za}$A2jjV71ib{W19q}sliw6 zRg;VcO6#+-u~c}Hgu?xP^$%~Va7@OEwYI_zvd7Q&_ z!FC#-N9UHNtsi~82HFk0+S)T=sXJ(<|8b z(6BXEoiaMbp4nx%OUz<|nXtj|0o2k{e?BbEiz8^weSp!AM$sTz-Dem_-8@;gj_)x^ z`y%D-3}@#YrO4h9C@2)`py^Idy{xf+As?wRz`qd;8ZZ{#+ZEgf2eT zFee1ghTZV4{o>xBAP-@(^>8^yG&Q{{+-U|e4)@FRn0)^`MDo9i-ujnz3`Omw0=y~m6o z^d>L@B@z&Xx4t8KnL5rQ%N{rOy97DHZwHRPrB`MC>Du!mE14or-q=>Hb;{m;aqlt2 z_EVF0&CAh)%HiO3++iQewZv!x(c!V68CmbP=3&9m(`Z#?=VOUsN$CQ%3DA+lY9Yv^ zloJ)GR*jIvb-RWiKEuRwE{|%3x{lhXoU`$#5SbfUJun2`5x08}w|dtG>54TU1NF)i zAg6m|gKWJW6A%C`$>0@={Ty;SFezi>j!=53WIm_?0gg~})YZM&ZyikH@QT5{HE6P| z=^O>3;KU&_6$L#}4NRy09XbS6k{=!&1?zM-2Qo-?94QJ!4a~b8DpLyqr6ifdS!(Ue zM^)@nL~P??iNv(i#Byblr zXQ6`$oSU*IG}-A!9jx|*ac9IBWD^EPsT^i5^6B`0m6wWa8Bin3WO&LF0L$F8$&T|x z)AHD8nF@Ami`-QJWMC-NUP#ri@g?$XdVd$ux(*uOZ86og`SWrdh(Y>V7sh$UTszAPVQ)vvR2mOvJGcEF z)`}PLb2hzY6ibClbMkXaR{&RDL>g#uo{N7za_`O?X)U`eK?ftRt^-YgD%hD(xz=*w z1AEd-_j;6m3PDswlA)!2q<^P3!^JX*<~YVZ93G=4{;gj{zioKE5AdIKK90XQuiHHb z^LO6vWq&nRwgfn3sB^40sP956M{?wmmHrzgU-iF`yzkMi_0?n<{%-h4Hef7RtK(|( z%4~;&;9@Ylv4*ray{s-VTbo0rqdXw6wE1#LtGPH3`)^_FYkW$iI&(27)#p?m@YUWX z2SjeJFr!8;Lh_|SbgEg8Ck4KfRv;Pfr_Q^Xj;@+7B$tbsl9%CYqpA3e#Uti<+$81M zYV%!;!uJ6gIj9G#W%6o<75ls>`hG(5Spx+F*QBfz91ES2_zK-+el-feJD3smbc9I) z;CCgZX=uQ(BP{j&GVT#Uq-mZVtpm#SHmCd+Hkdu0TDu-%Jt^aUsB@_EK33h=ni_|1 zKZeUB3O@zFku-wfB}u+GLW*A8%{I`alP zT~^k{PeL3uzF?)U116Xioq}6D#1?sT4@tc^{2Jcg96P|NAol|taii{DNfJp)npQl{OLE;69`;$R4#ElZfHRzM4m;RYFasDqd{(a z)xP50c?2*HqRfI!IlqYTj`#%U2;2tY15$0jQ7^BQJQ1Q?RkeBS{d3G8bYp4yu(ue8 zZ1BOocg#PdRAbCvYkZDw#u=;xo*&5^3G-$;(zA;xsPwP2Y(_Ai_<%ri4qxM2Kqj5k*SoEgvQC8OU4-hfHBd^$3796>n|-XcZFoR@S&2Kre(aC|IJ3E4WX_n1BCC(&GW;=;8i4Vw!$Ne zN$2g<0$SYb1bkmAUK+BFo`0LQJoFAMl2lRfX%5I>yhiaECxvft>@ng+}yuJbY_Xg{*>RkvvNFjg=_0{uHRbCH)@L(60&jj6`bG&m0sG%Y3F*Hmt- zWmmfN7`+Gw!1DlJ>ogr6_iZQFH;7!bMie+HMA<=uVt zjlzW9^n(JfGr=tJlVrIyURa?#sS(yfvr`{D+JwC#w9BD!&3i}u3vup-mBa)#s4?Hs z9lvpAa!z~;x}lcV{!_3HCjnk=JqN{v^cC&>H@WIQnK0$*lR{~U)>oWms;vWzR-T`ps`U~- zq*QMw=*?eHx%ALvw`C^tsqUde2OPEG| zqYfzm@!k*67V8QHV0VScQ4Q%f-4U9NrI-`;ZQ$jjE#Qn{aUzwfs>#8D5C9$_O5<yo1DB<^!>seOqV`G>E=x)w%JltdwWBwGzx1wdzwDP-|EKAVwz% zf}w6*eGs-(0NFtAkKjzr<^D|(nlx@(O`TnS0BTtBAbL+?XcMw{ekJv za&QGm0V7M75%rc9IOv^%ZCdqa^vP<@p+QFLB1=}J=%f;8K#gL$O1Q5vGlaCUgFdNY ztq3TW)V;&bPmqXTRvMJ_`QIbE*eZ-6$LAr68P0rB=6e?@Z_M{6#rHpOXfo7KOg_|t<%+))6-!7^}$)hT}|}%VwfSJWR*g$ z_{VE;KJOD-BrIO>0+XS&4z2_>V;;ecuD7N3i2>Vx z8?Az`HmoV03VH@qu)@jW|VItH2gp3rb%qO@o>M_u`0M1?r}Aq^y9 zyMm*GX7fY^B`IZZKG-L5Y3=yaU`4+w!Ya8XGGnN?xqvqy0G=y!tV!5c8NMaxi`%DZ zTo?^3Efvu{Y>5y&ILcpXr(DxIH@8SO`YbiXM$3V2J^_S2E?0Q~ z0@~=?nwd}U`XQ6Y)R#i(Z`^jc=N*xwB=g0kL4G0k=zGEixH-G?VTFUlbtoa^Zm5-6 zy4bmzF(&8xSeQF2F+8ssbo&RdmlK%flTss<4$@U1Fv;X(SQpI%z#d#TAqO|nnOiFt zd_TUnec5Qat7kZI%+AD5{WI4FUhDgIHLRuokNwm?`dgyZ87F@mStgXzm}maFR(tbU zYFXhX8?|rI!ls_M<>~MR!{Ho&GBMss2Mv(UXoo-(u$muQ;})@j;V)uk&saBPjiBLl zUM#!7vR@uxDjm`#&gD6UX%UK^lbP|7)fa3~Y$x7Gm@$Aj@}`SBx_+YvVIUT*H1I7e zh$izVX%4vrLpKCf=uM&ymLWNS2u@STGKYSIWZ%kb(Eb(#PGZ8#D1FSE7(1ZJryn8YG8! z)0_j-D99fKf4yff({y)!p&y8q@54oFm6T2zj*kQ_5KE&1f=W$n@2RKJK$64UwiXdQ ztVesj6g3!y%dG^5X1K;)GYK`+z^}Wh`p5L@(^=A}72*(NlWLdOc&r?%&S=7uVV9BK z&%M46FV$f^2glIuNl0*uYeaABdnCiiwBy zHY{no+JA~Uc%M1=Z<=6+>!Bl}>h#q6viuj3rgI)0!6yULu_v1y+B`4KB-n(--HqG$ zd6oOo{Y9@t-{(%AAh^7nqfYpl?Pz8%zheoekTOPaRCJN~l-emh`M|Ji%>*|<6G-q2 zOP48(*QzO}%l+t+ujlxhKW=bkshUcx=&iX;oyy7a`u!$5>oYT+zQ;6xd*FGh`{?`g zt?$VM?D@1}{q`j7N(U+0{W28jeMP;q^6|g=iG20r>8+&K1O6`y@aie`7=${V{7(%e=IOM)ACt_=j8h`BTfJZ3LjJeie8a`_LQ?|41A03{mxCnYZ1 zG+yW#gkbhbZ@;j{h<KEjofl@$OD!h%kHJTJ-`&0bmPA}vc?>U+hri`XxIZ+rz3 zNWceFIm3Qb)@je1YlK~j+k(^bnU>pb{v}$*lw>IXZZ^EcYG6<`&Ql`1<_vYi*%xUX z%_rM2|D;$rYHfKEopD#aQ35E-5%hCy5cF#ET5Irc1o9lMx9E(!yN_J#a8mxZf8>wD z6ER}d!tP0x%w?Gx%}T(!Qo#s#`_71otdF>xqe$QL1i@EqGCD0?ClU7fY+}veNI#Wl zBtuOzgpGn;)dmC7wf^E7HCx~H57p39xPRqIae2vLQktrSs@1fa}1c;pnS+=|rv zT7J>M{+5;d>9SA%KJeWGQ zjuyRm?Zso{wpdIBViZ}77@4_rHw7@IP0)IA)FBjFF?ReX#NUc2+%;oLCYv%4#p63} z&;!y*-s67sz8YTfHO)SIdDM+ld7MQ#{_Sjp*fO-+FJ6b`bAztJ7b*SGbAiIQdQ)7l z2OhMFIz)MIA8(FLRxH#vW$N_HBnGQaC(u_C-5|I0l=g2qfthBvsrUjp$OS8`2LM;A zK4w$S2YaJ12Z2GVswCagsLa9GF+yoz8C-#`IR?VWMO0Fo@Fn#38sZ-UJ#o)OeqJ>7 zTY7peAe9bLZBD!k&ZC#p$jHRVqQpIJW&UH#FHJ*67O=F2j0w7?o@TvQ3ZCtyb5-gs zbcNSu_0RVA%@e3(coFe3vbJ`7;l^_aa@d~!*+@wC!BYNh%iI}7RZhO?L1fm&%u1~W zOGdz=}0iT}lrW*xX(*?FS&)zwmQKNpmL zf@LWk{lqBegTGYGWD<~>o5#nV&6R+FZiMB}oH5toa%VC(c4OI+!#ca8if!?pD&r(w zls%hm`sR;1v+E-aKOUzHGwd59l3Iken{W+=BFO?GfPkzRr+-YMl%C2>jeOz(cYJR} zfq5A8{eDXL+Vbcng(%TsBx)ZQ|Ln3wFe26P?ZI7Vw)q?f|LgG*J|&_VdfI>~^s6cc zC$ebDsE#Fver0QqflQ;Z<9}Xd+D}QYY|%k-P&b=&oD&*zH6aqIIV=)7K-|F%Uz%?w zmQXo=DZb>onAhdRI@`$bdioLNW4znaU?l~Az_R(Bq4!z6!^5n8-F;1C$7O0ZUP8bd zGFR4+{T~kp>{yOaR3-3#G@w12O8yUV^5WoIf4>98xOBd{&_is$nUNI}dc7Hu*4-WN z*s%@Vu36OIM*Q2GCXw;#)4M+`)6-~2b#h5^cU0@9A7Tz-3Ajyq6#OM2oBGu?NhZ5A z|4-X~122SQOJ$?&Sx`=-6uI~nK{Q5D)Ku)KVLlKWwKcf2-aLNYzwEW%CZ-#V1)Z^s zP7gcZVYqXN*CV7ChL@K{%7IY!KwZ&@xN$w@_+4g~8}l*FwXKQ&bS&Vh%V)B$b7mPB ziSq1Te}pOWxks|wK@HRgy*F+byW>(v>HT$mA1B^Wqzpyu&tVqpc~@HI;fS*;A71hEA)4DPRbq>uNm`zwMCT@u1m_O>%ut{#m#dwy_f z1C)tMOWzlObGcbOU5yFx@JbBOb0x*AQMmwS?-n&dHqE`$u^cp=G6jpYlQgW<$Ez&q zzUn-4$^EX9%;yr%A!M&YXD#1*o_9ELbmgYLe>}rXD@?^!ug03i!|23mgMS{HF47KAuJCJo) zy%uQGQgS#4Za{;OR$a5$kZX7VWW|VFh?OVPuTH-*WH4_ik|nATL98AB7m_#K_opbB zm32C+sUtm$3foUJzXb)Q+tEl7w?FkfXLYw0k*ysU?N&$`p>bIV_~qpsAyZ(U{zj5U zot5SMTDRy+! zLC{7rkpi6-dhPT(d+#KX-;nBxOU6xAT6TP1t8cA$N>otPd5b8=H;$0M3t>Q_h_$O) zmSsdEMdenHNB#9cHZdP?3$H$mKN>UDwqLB`(?l_2f~p;fSwZd%=#$vf?dUIo>k;d0 z`@XdoX5Kt7F;;5_FS$>(%>5wu*^K$80Tnwn)_4IMGyIeg zNTU`>lQJq4AIe$aFzG+*alk?H@9~4a!Q&@^?6m9wfg3dI#v7_`53zQg%*UiszFyH_ zC~we!=zCY~ms9BL{l&1q;ggV_jFBE_kT-Eq3)d8xY|i+KjsZGj%$Cpmp>k(MXlKsN z?(;Y?O7R!X@Ygjb9EBH8ar3XlY5&0Qc6S3t?~>xemtKC~3y+ufxxMMmo70L(7y`)) zb}cr(OPX48QLKX{5GD5(>D?0$S z)8+Gva9qnD=ciA5UrSurVTd3oLnt=_o9WZ+@?j3MC2U#fMr88gE7WbyBi(Q}{U1qE z(kYgp)r0f$2&AvbSCB0TC&dqy`Rb=EX>EYScOy3iuPI?=8G!Hz) zfO2EA&^h_ch+*z^G&%zvAuhiKo;<6|?uR*(RVtB3@$|WSFViu`i^u0Oj>9p)54D`% z-^5ZQggCu99YUHeruoX;i0?g%7R7cC($OqAec73?4P!_1Px{Obu@U?h{_MW#{L{Oa z=<(;_+Uw!G)%;{T#`wEy)f%pOeNL0($1os_2FXq_Obta$IRxL zS|5vU+p2QS&&1ub%&a;r#!XOrZ zCe=UuU?*v!*AwWI@^bmwk&-4SMK70kK5fcWrM`#zdwsF{BOifX2ThJuRd&ix1J?3; zp}zfWc$RTK0T&WugdkLD^q__qZD|TM0dZtYmOi$*a<;s%aH^Ja zbu_B}z+WAE_G6APT)meNhp{feH2%+@J|gK|< z(FImKe726a#}+Z{uMx?Ri%bH~B4-$ZA#ENI53U7K>jRy(8`TrOw*fUFDg=kHsO5@+ z>QITe+B`2&kWc~($>3<2%FCX)CDP(jkX>)91H60UnV(HmDyK89!DDzS7#wSjDazqr zOzMe+g|M_M39&X}5-A^LJV-pl-KnA1cmVMwP=0M)X`tWy zAxygMXYM*7Bm>RvWYOzOUAsJeO}p)VF>P1N62TF;@gTo_$TIQo4}H@EN))d#SBzll z)|*1l7vo@D;*jz0)F1CQ+@s5~VpzK?Ln=2*#tT)Z_ELH8f}&bZCS%L|y)u^auzafg z9`RPjBb)+;Q85;cwLxqFiJ@aHDJrY3+0iaWd3^v-!(;!fd859hr+w3Rnhwlt&jzN-d+z%X;i z2dWIF47b*gy^G=XI)hgV{a81>_x!)h1UuuqJ-N{OJ=M@w3+=PLoWd`zG9zm0Uxnn5{(}}`|j6Okw{goeEYfbpmn-@DgtdcmTV|JldlLVv+`n|QBv+cGY@?ZvQ4D~bbQ zBww%j=@B;~zKI?VocNe62}yv1;hVR&l7Lss3iZ~Mnm-v!D*byaj+NZZ(d=NNd__~B zUHlXK^~w3BnlqQ8hGydG2}kKtr}3D}LH6{`QI)Ocpcs|!1v+vN^TF);#a+stB>GI$ z*L3@+q6G0$WLgGVlYUiUB4AQV2m)$| zQNIDpd1{#TJ}I7?^KpFF{eEB+sYDQYeK_V8CH?7WOeN|L`_J#p&jN}7)+tI3*Qed5 zFB5zt&doy46_Xqf{nK=j&!uBmyni+(j=XQKD=;oLq~3-F3&ZZs^Ra&PCJ1Vr%Y`%V zX}_WDD-oU4*E(tgdbg^)rj({s>k<@MjxjNJ6Ze^!-}l`F)47huu&=jKq0-f{xp}7& z)n5o5+BeVUd*OA-8>f zK5el+SS*<9Z7YUJjFh&cT~Vo62aOUwl~TkAQQ5K*l_S!I$eCg6`$Tr+!l~^|VoKNs zI~Wo_H!v=@CpI3nsV}Ee{9=$wIxPz)$mpXy#2O-xrv=6p#d7B{FUREVRoGjB3lzvh zduoHz33FNy-Kf2wuQqv7@fIAVP2)m_7M$v^4a)A8+_vE`W2|mcqy}W0*D*`<37xIb z&`|I)mNj+?Spg;(q?;2*HRg{~O1Vf1#QSCHNp&GG%LxSc$-*517dHc8(Ih)mi@(q9COh|?f&7cL|ESGfc%Zle$?0{ej@_r?cjcE1Tx%M<-Qq zlaoXrno7aOzV%a=nsc!5f6J)Eg$!wKy2$#-8i7 z^12S`Z514hJ-PHu;gB}Qd9w6A%gxoVNwk_1Tpl|?2LzCWJd6(Ps}?1BafBK9{!=Th zAKTIMv9wBn($K-fC)~8{+iAMcy zGTAYu-S7ES%!{en{34~0D~hcIr$-nB8j{R87>9e6>&^ZR2? zvz_sD@9ciPuJP}0bycWekhD6E&CbHsB*`%2r?%%%t7lQV8S88<2j-#aD@N`UcY6(0!v- z;ruxnLoP#JDUC3c$`)54^A(^}Z(vkww-5}j1DUF0kcf)Yz ztY@9q&;19?o8MZq*LUyz+1I7OtCcU2@h9w;kfeP|a$*D;hTq=CJaJg<=CuVXHyQOJ zd9Z!gZ;o1XOe>fc?>7qegk#n25F#gFdTn!?V?3>K(1nIF7H9!;i3uPH0fh!ovZexw zHNaLdu$L|HqzffDqfp#bh8PdZYzJ;NLzxn|Et04+3bv0%za~3=^QN4T1L)Y{z(K*x zfpWmLu|4*_VSfVlWf$#)bUZfqc5&dO z7V43y1XLWt0^(Zw_h*9VrJX&oK~1ZdkJiNGq~Ybxzhl_H-6RK!-$r2@jV&83m^>Kr ziC^F_`3o@_Y4-B>n6R}))3SvNQD`I{ z-2y-WXfPzH`;=ZueOk{)X5=ig4^u z*mhKN%Np&sNm|+9`OhsR*(HQJ(ouo1AXGJZgZ6JbTktSq_?d9bL*bA4=V<$dFOG6z zO>qxME=>TY^mI#j;I7IC;)IDUBt~0NKRhT<#isvwLdE6eI6Hw44N!O(@i!u57Kh#& z^4SlkS$1Qe_wfAHmCvyJ*V7WY7X`_NExw+Gi4)Vy<%jO?2T+_?)!3KRMDMQ`_s<@R zbI9Z8nU;OMBBuSuK;RRz1y@JiIis+15wG2UMK-+|G9vg>iq&u@rKYCZjtIPg)LMGL z%=$N}DH*k>`z>iFW6)JMGX_kU<+G2#>+)SHns=rauT6}@zepUO_HScQ5GlsUhMG&H zjiW}Vyi0@z{Cm)3KoaG;XJ{g#WyDtjCl!MNXDyC1c{oARAaOckG?Z@)dRV57RKI-J z$sOQ-rsj7ID~+s$(q~&qAqnS;^Q*3WKjJkcVfE2ll5(83t2p$KKH<;}AU@buJx6R6 zcXRQ>7FXtRY9Dy_>s{^BQfkRY&cl#eSEy!9IR*r2scP&#h^Z3H?N*PjCu$ zh8^5Qd}vp(Ql1C~R&7RNqI}SA@@_!;)&jE4>DeZ?vWdqg_%|#51``*U|90l#%C@2>unrl$0j-&Cf0@wwX0-~cti_kDwsqNb3 zv!Vq56j655um(s%%NHo3TOvMSkRMP{iGOFjRMCCBbO%hOifO~w1#Xw9W_dGqKz4?H zd3Ru6DZGN9QiAqtwf90t;Hg?{B-M_gED#!4tQhOaN>?2R9G%)?+(+u4)udF>H$=h| zc+H5k^1H)<8i6{nzsHlK2EU`3((X4xA%|{t-(?vYQR^?l66bsQsXi<(ud&)%6$~pv z&u|1tc1j6+m}MIIdycF7>rc&+ECP;CZVGl-l2oQG9tV{ZpBPL`TC400pDRASeV~*s?B0y_4n7z{=tA9>^XsL&i#R0lpHn8}Z;x;iY>_M@?auc6lVbI4a7PfCs4ZW&s zPki4}C3<6*i?}+;?%k;_h1Ahv|9^ej{|gI>0rJ7*QATIp+mi=#le^%l;rZ@)#1sGX z=lS8EpV^YVn5pv|_RmjDvfe(-LH(Mk{M+jRXqWwyiWuO|hqvB7m5&%y7Vs_qJm#zf z=u}&%ZpLmA!kZE9F*)Tfp?#l027GmYUu@Bkg3}Z*VRNDBRnrW@|6!;3)KO&MCnG1S zdxkTuSZ4g>swqT_zo@kWiUbD(K#>gbFeo=&lDtcGQ|3-c&*dFojkFdHS`>Tu4=mX* zovBK4o&&**#g?m`ej%*`mlHF*nWyZShgjO1V->lVGW;H=0~w1eMu4Rhsk_5^xiE9Ja$&~4ayL-{!TP72@3G)NR7cg`4;4BiY@AqF| zX!+&l{;uD0R?jTg%U;&X<&wMzA&xsHZtq!Mq`F4uJx?~TfGJ{BiSRg?obFWddHMW1 zEe;SF>}N6S#Prg!y!{>L_XBN>d8;2w9#%aK48q_OFW1_RF4k}KEO&b`vR@D}{PGU5 zpZSh!^)A8Ds^H1J)4!TJ8=^@PZufOJ%5ai!nlVi{RdEA0Pwn+(gJplQPBNIEZk#nU zrb_`oDENkGik45`z2_Jsy7&(o`JWl|ApNH)9DF zTAZkD$Rj?PNLi!pjN~^`IPidCv0Za=o9^!69X%2s zyM#6nK|OByU6^_mC=-(?BXr`RQ=4xaPyHo?;)as79U<3lz=cW)jNEWRt*_!F7!1E) z-vM(NKgKW%A)Bb3jd|Hsf$5FIh`4EQ$qx{Vx23&={ZkeLNGSsA##;;#Z$}gcwc3>G zGQ|>k5I3t6eA%1}%ESBTu%!QtJL2ym=#E21bS%CIQ;3STMZ%0`G^1mZZm?TH{9t4G z#imGb17yOxB062Y7mKgoDB)wUJ3$|aVuJ@iiOxih*$QX68=YMt>#C7O%GKG8kL<_X z5PJHg)z$Es{GG1=tB7Z1r!v}Wd)2x>6CU6Gdgo(I0bBu`p~lO%p6d^0f3hMXq3XKB z*sJX`SV?`xg-N2iR0ex)8GpBOrkC2UYJs7!NxM2ke`(gUm6)o-=f%#SLm($9wAIMm z%!0=-?I|S1in+KxeO)Ga|CoQy&RqOnl3{k|6_)zKdIX6n(dM~tkj3~+c8FM})!ih4 z^L=8T;qKD&=3>&#^GtvL8MZD#$>5wjcIAS20XF%63;I3Bd+ReY65N^m;j7s$ikELD z5S@$7M9WR#8-986_>Wzw=>(BleyO_IPhI%C5fOVa)B9}K(0*GKnM)$ZH~O3miL%W{ zch`wQmxvr9OhB(Wp)|$Fl@5wTX&scz=4oM!xZ0bHg)a{0WUo>yWyhh)nOZN;j#j=6 zkCa?EQjGpHFP4o*_grLgbcfbksl>x&bDQ(^x%F-&CO#-q zBnTx)8WI!=!p9QwrVoVm5s_|3!Intdul~N=>UdfektduR&9^xh(LZ?|lO3I7YVm(r zfRWfTV*U&AojvYyO89b01SLhp+#>#xPt-={L)A|%3#&Cqe1OPATDl{J$ildpr0&)X zBTYJP3R`1DV~V-W$Q# z?&g1U=mX3ysx!+JFOO-m2V%&IGkL8?83B8gYtP%WsNeLLroKv-=rgNmH8W%G5WtE= zFFb?9N~QUpWa`KzEaAGY;cye71lyyQX*jt7v%-ME5F)~4bEi+a8YmJZ#9E)JRHl+C z*q|+4wA3)Vc%8#}-bjqSY}R^u*T{wq3&1(>PAw=Gn37BSDXY^r@&i1$3-cS!l6NdE z&}d5-i5gs4k0gr3C{`s&3voVQ<5nt0tp(DI8fr<3CyKMMHKC>j=|Gv#O?ho5*f&ZE z3O7-;$Y{udgS*$7MQLYw2z+e}BDUF%Z>}>7#vSptm z>T;*GPgNwBuLq4o%nZFwpzYS{$ugSRjtkKRzE}H;4u%tG_8nvWyz>>hHeWAT>Tyt) zyB2txMp5Mr=LXnyv|AD_xVm9;Sw%mDgas=)qcy?C2oxwp4n3^%`8spv*Mx@&X#tTq zS|}JQ1EmAiQJ?tfrGD>7q-S*U)WF~SJiAIJTY}f07%%eNvOsZT?GX=~ZDjmOMXjor zE-bCJ(z+=vWuKTMH{DJ0=Jws%vZWY1f%|#UCB2~Jv#Qu{L_R7w|3FvqH;cyw+CGj- zVgL?5))J%$Mh$gOeB)k~>QK`W>hq+5or9=6Uy-2!Q@gkLRoR!WbI9{)Df~PS_Ag4C z`w~mn2LD*=&tWR=^C3o$z4V}Tj}l<7gAC?JhpNAx-?f#bn-k!EasR<+|u%} z#7y{|h_LnE`aF0c+{s%@eOLHbkp+5!I4SnDhokju;`Ch4OWlW+3zs(Mh$_riLEfZ#>5@4NSn5CJ1{q+0}oMC8-!mnY1Moo=)TQ{+l< zGuvwg7MBBU1;X%ck~H1?m24g016cm@&YeU&lGCS`^x}=JHnTlb3K6mGR>QE7 zUY_0GLBlNDzq5h$Xg@lW7s0`Jv{bNq+-U*mOWHfYkg*M9cHS%2s^%n6#X< z(#SL4d`_GU)l!2&hSb5*CM{0`RRgnvo^)B#6-iHHZz90&3cavaH1d*Ei@COo>UbdJ zKu-gjEwI8cCCKb}Y(9dF=6aC-+ElEP#_j`wUJ^8Jr3hoBNNng&aezhODl6(iP@U_S zIxIZ=F7KX)x>uB}5l%t)Iuye;#mr@FUr#H;D2k^Fh_Y;|f5GgDP z6Ez65G%Me-`~4OAkH+@oq^->?ia5hG_r+HLdj2Q_G)EYgE{uB_~Ou=LJuMB?z8YP|P=#y$Gd) zN7?92$*3o3L{E`zKR}zo~=&V?(u$j%=vz zOm<|hCJ!t&kz-!htI3cD$Byfb2C;L>;>C?Bf?tSeQI=3A^~%4`SBt|*&z1HEGN!-$ z5*{&(*x?@MyG8%J8H0oQ2)1Prw0WHnpDll+q1PWO_*Yn7CacC( z`#hQ$zZUa}DH5SM!*O3mBv!0ui@YS7Z21zvGZs2$iNUk6gFZVzJsqB){4T0cn9wjK zw!XplSK~v3@>lD>DNXAcOclhyq0@7W_pWy8yCLqGQmsxol&YUSd~JWDZMy8l8ZY*o zyOepTuK(7!*nF5N=$?n@=?3q~{YlZ~X&k_;Aoe@(kKWS!lFb@c`a;B*+|QQx%9h*C zcx!_M=kB{L!D4{p$(7jMj^9B8O_K5p=*P@xn$n4H4nYFrMGwlIu0QP-tY!2X9d~Ltpr2^EaC-2fk1^2#Ko|DO z8xyRG_7!)9b6?0z$g2Ena1yGMXe(BZCCm~w22Fy+grDjMnQ_5hb~Oh7848RAB}=wB z)OhIxM=MD#5?Ev42Oat;GjXc*5|s{hd1I2I4#r&N_w0WN+rTI|BGS<3>4S|!%Dd*N zwWk$x!E1#tqnz$&Kml2aIk_+6;Ki-L^V@ka=xbT=bv zrCx0l(@BNxC7=DFiT-)I8$tSoNM-Wvx7UIq!dG(G1RqMn4*#Fw(9mC$4ryd5+N8?z6@4e zmsh{=rOS1Vvc^7HBKB$v6mv6J>QNXU>Qx&DCcYlb zPV6qVeGbt>6AVX-KBxQb1G$ynn1P96G>(V3VoQocLG*kAq>4d5z1p%zzCICBz`KkmF6aBF`%eom{N z0l^3)${kIjkIKY2JZIF>{?Ed%n4us^q0rx%N89u4ruHX`6C&Ax>FLo zru~RWMV6xW@AY>hKHfE*E#)tBJTqZF%Rc{Yup_rk2|W}0_^xxoE4{kfJFeu1E`;!qeG?bymz?FnD?~Qu_b97Y zA%Va$l5~-zEHYQbv8O+Ra=f$`PZf%A(w1o8d^{arD3<@09t-gCFAjtCtk`cT z1Km(=^bPQX7<7*2-8QCKY~MB;G}jw9wDkM6eZ(_e&%Zb`yt{MqrENFDqFDLW?5g`d zo_mC8V`~ssHSSf+p6FAE44dlFlpyCsDy!L?_t#@F^4IO|A3lGCLZWRqGSM21XxAE& z-0J(yaE!4R?%d!qW2pn5>I78nTS!sYi#D?`sKouSsEof{o2I+>8>~m5qEb_I3o>L^ z!n&7zc-85&&2V%^+FVj}NZxsB>G14%?JCi?;HkiiICcUBWi**ys~S{1%{H7-+?SJR5MD2hP(ZvljUh7WRSf)=6r*_Us!cM}>WjMt0?{TxJVKE^z-Fo`bUESUAi?2Vcg z1OjbGm(JC|Ap#PB+U*mLj7vmrxS}-ov-F0@!Cs)&1Z0gyIL*SBy+7o2_Zj`0Zz2YHA|^dm z%Nd#|jupGPaNXj&tVrIMD8P+OF5*}TSX)*2uqcS!)bLjOJv1~5@+r;9#$T>69Mo%q z!?m@bTo5CBN=1CqKWVFI5EKnA>0MNd4QMdlEU8#v-M=DeynCxH9{r1f%u#j5k3&u= z!=`6$4xa&Xn^De?Bf6UuI+Y^^TJwJn(KpsHfzV3ax2TiCn9yXnR#(aNtj`Y5lH5H< zhzY2UsTZW#(+$Nl1sie<>*YOX>>g(n4s=cUI-x!E${mRQB7*=+?i-H_dw2pW0Cv7= zt@gVlFFRuiM|@l1>xx|*!bmce#IQMehkbOJmKq!4*CJVj{5JLn4%^IU+W_bD^(J@k8pcnX z+?X%3o2R3)kZyMvG~p!w{Xg)O3L+VCr-A@aDHh~tBc$1L-OhI}s2Og4a`&4Z6eGv# zD~h8zfdb1270n4a4cIV1RN@`jERXq46A%fN)I~i)oqBmr&so6W;{UwXkxxowMFYpg z*A9`;h%J_}!KidAvF0w%dFzn5Sf{zO`e^y!*jwfZHy3`rojQ#TENME4k;<_74){CC z77PmPotrS3G++_);W70;NBk0l;A=7Vf6OQucFRzr-x?!T)?U3`wD^_v>UC<4B^jOK z)f4}E1~Qfu7KLTFEZy_HuMS_lYTa`(l7riGkdVQqVrezIW=6q~eYRXix6W$&=~HbZ zWq^6~ivrK{q~TmxmZ?|!lT~nte;Bo8vT_%_>MP{xnieDPW6;f4Dew6gu{YFt$xMnT z{%SGDA{1->Prr2zDmDy`I#3c8pw#$E?q9iU(Av@K+3L;^1W*F-?<+qwW07Tbc?D`f z`#UFAS})VXRns5!)nE_|dIBV%r>4qTOLxuSJt+7>S7|RRB>x~lDIuAAHB9eI_j>Gi zA?q75+TYYXM}2%{tY>WQ=Au04AIaNOr@S}_mllJy9pv1i``Atm8oN3(3Mx^Sbdcu6 zdDcHHs}h<@8xt^~N@%RISeVqUexjYW&x_-k8ljaBG5FckvUJmOG6EyPgD1}jL%kDImu z8gU>M?@n>=ICAaCDqRHh!R3Zn#II!MUWxGtbx(n58S{oP^c9A<2HGg~V$hK2oKj+> zhM_cYhWAfd@%u49&>28M{0F|=M<^kfLP$}<8&?gPFf`MBlTk-D%MeCU1bd%bAB_2e zP@6`XOaZutl|g4VZ^O7CTA#yW$LV#1JOmC2;z0_ujK_v_Z71zwyaF}Qk{P%s!Z13l@x@y&t@BA6N@Nnp@ZLHrg<=nIRhF$b630r}Fg9jyZmPx-d8CRp_ z{CM+nPt|)_$^RhShSfD8I0aN&sAb@5!@!l%=dKwf0HES{iKFEpI#p1$vf6r)vK5Wx ze|ARC{K8W&*Pr! z9gsCCzzZPR`^))b57Cu1HkO1>sb$xT?@S;c5c~&Mha?sDapK#)e=g29!EWyOXcDHt)uG(XqX$W{`enOjx)6uI>!U4AFW;Nu zo_y0aroSwmjh&7Vm>EL2nR@ao-oY{k%Z$& z?!ud?%t0NZ|GN8bgDK=DoS=4UK3x=n?|+=r1FlYEDIfoII~`QvUnuTioU9hioo}Yj zM@QfI%5Sym`6Mwr=M(ay>L$w5`#Df}rl_tj4Ba!4fg*j@Qd#t7zIcwgx@fxA~zP81) zn)ZqxaVRB5i*b?ATD@Kq+W)nziM%>k>_GIfoD8YZSe(3b264EMC z=6t^V^G=|AcXYB=h23CM*c12j-iNF=QRY@wz-r79B;c5JK1DzKm5JO;7BmX}%cY*P z{plL-)u|U;I$dWIXfnQxqF-M5bAlk9tm%ef0aYnK7N>Zt;Z*`S0p_%2Zbd)SlT?kj z(TGzjZGsEsV-KaPna=Nm#g$?FF!EW#RX-x*VaTHWso-y%Kfh$e7aW=C>|z zVhWkBS{CQ?x`94HS>{%e-`3Nr9xC)>yU_C=VTF}A6oj?f8L1_87@j4V!Z zK8oaQg^i6)A{ZaILGHBx8*WnI{x)wnEe?`9g-l4|g_l`8OeE@|Vg{xLM&rS)b0T9^ zxS>RmWZj0JUhGCGT%Zv^gGqJSJo=Z_A);a6of`6e|7>6Sp!6^olqRD@4Cbr;VbtSd ztay9#irj|aV%66ZOku9vVVO!)74IM*X9@@Xkl=(vgam-+(M83lP>z@}-5jW0xS>?= z_z#Rpv4;R#V22XR;YT(rz6hTpTUpfyZv)RLv_1gTpLLbgkT%=d$-nU%<^w3SvUwa` z;=T-MkjqEYcDJ~+$gVbky-2&efEasCTF_vf)=DM5Ndl`t!p%QPkDc0+bw? zo|1N}kWz!wHSf3^64Y{qKcDc*L5XKTy>yi&nScAKKe}iIjXvhR1KS|IFZ*aazc|M{ zfV@Mw@*ICLy(gwtUUSc5jWi7Q8-$%Z;d8a#AltYf#vNmRHnK++6v(agti@fUVJaa5 zy^m4#8WRht0@?W9F=>kjBpUNTCidJZ+)PUurS}NE&XHE+?h_Yj%CH%TmsF}4HJJ~< zO7%C!#H?nnnnkzm%H=HA`8qE0CB_GcBuqzgwUZ#YG;)mTwZm(x-qj=}5^HRS zOrP)b^zUqaueX!NMb5J2YPD3Gnr8e2lxA4Wzb7wctyijkS~%#++1%k`K*bOc5;74J z_R#@KF1NMaIeGd53f!UjBdB9y2(MMP)W)2jT21AZX&8Ab-wyx2mV}dT$#5}vk|@F~ zRO-&Y(0;t$>QX#NTU+{@S~hp+7#&L78qIN8?3{>jW;Y0UM^^tO(xLGk@`14J<|O8P zLr`+5t#-+)rXFvC-QnY>iRS++%lC`jJYTTu z(E(tg)g@(f>lxXU&nMJDmBTqXG9$l}#U3!}Bz12J#dV3NRDx-*`PUW{>1lHc5G@H} zWPstKO1ceYOXY)Y7(3l_;`IHO4m+CYP;bqu=cY!JpIC_p1QQk02eH(Kuzg)TUH1kR z#9m9q9_Mx@_c<=NA_Arofu5#-viTmj{{IjEU7s9*xK|{w_0NaV+zxmHA^cNn{3QX=D;OI+gjDol$C_#k`wj$ z$C25zmg>5fHD#}Gk{i85hTB1>sBKM$P=;m92CCoh@^vATY=i*LOb|t(+7BRiH-G11 z@!4~$p%UJ~9}YZ#A-MVL?EM%{d&TFS`^@!JGu}Ip*lKIrU}-5T-tniyVFevDws6h_>+op6AE*?aq0xA;5{&N9ev zbXPh^b-t}g&J=xb$Rg1P#pfoi=tJKzPKt)08ivR(f2gg~5IQ3O>Al4J?w5!=V%KV% zpaTSj0>CHg*&-98(Y^MT8r3R!$>EVOujmbfKr^F`v1J!d+{%m+7IV(2AwO9`?BYa8 zkjoaQ4zY={)uoOHu3mI2z8+TjNM*Rs60H{#A#9Y&>~4#E6N^Rx#@_17zbVRkEF>5jE5yEoDts26h*k)Ejiy40L zUW;QoIX7)XWU3LU{YFn0=>A548Dm|5aA&L}!mWeFl+I8g%==bE67s12CD zF2nP+Tza>gvgCZz8}9|VwhUclofNgvB8cG}~P4x@Hmp8u&;!4`lcjjMZco&xZ>5-^Ib&dezh zF03RT`d;?eL1)jKtUmMIo08+sDi==|8}_i^U)qwUT4){ict#a8oJGqIaO%+rcu=~j z-YptzZTY8nz~il$kpJ~RGErmHtJKks)}ILP{~QlGA$ZC*C5U=_j+>;0n~;dz4JZTE z?#!~*;a3mOyh(*{)UFK~N;>Mb#;a#H=j+4NY}?G2JClY;)`kk;d+e;YG2*fwU()xk z&bKp(7HCJCw7Wei%5$CdNCxv0JZ1i0+D60Rrwd^jqYu4%Vzx^6yTJDHxW7w92(iph zh)n7=hrZ0z7r&87LCk&Sp>u>;60btHcaQ@F6wOp@AFqZ`D{IOuWE5SQ z#ecmkbW-VNds~_$l|1<6Ye0v9?CEvg*As_jeSmo0vN(j=rX2l7MisSs-?R|8ZoLnx z#0_2+^{NXZLK(J6Opf>>w%~KL+QFS>=eQ%pNu`Q5@_$)?Qq(Cl*}cWW!>2UAwxlhs ztAJ@#0k}q7@fh8ed&d`#tIPXZ8njDMEzoakclQ+8+zX8 zS15Ed-|#dxl1htfqZ=84MSTC}Vw)Rdc5=Q9zlhiW={62)c@`zpRB&Pw$f1{~VjBJm z3%1qm_c^=8DxJcRCf(FGh&Vs}0L|#tjZM$Oy;%zYLFX>&>~%2vMna&;Dj9C=%aM`S z_8+H*5lZx71+-^>fqvdW8$$040*Sh*F_~lfY)jOQn zA`G6InM88x-ug`5W?de0<_gPC25Y}?FzpkVf+9C`pG~6qO}U*Y1aiD*aX1D6R`CUm zfwQcAf{`@X6rzC&t^klJKW*%LHm*<|@d+5E9S!Y^WcsO@SIJD(8rjKY0OD8I?{HiM z^aye}IvN)Bvm5|WZ;n^efRopDfUmsWQdC+L!GK{d1_7@b`6+SwQ3d#N7A^=}R@Cj& z5FCka)P>?3%GxlHJN0`}J1tHaslLiUW3c_wia(oThWvzY70-@cA`@M}G!WY_L>M;l zy&WMyP96;p+aA!y?RtIBS66n;@~oKDA|(K=poUnF2k*hws6j zm=anrhLl(kz5eN(&`o1lz2)LqoT^_7gZy?F$cB^rjjtyjn*7&NCB}wysOf<0eLGul zXS^~d*-I*oKm_fY-O2VcI$jZvnBj6G#;CUPXi@=P`GPH`=p}(CoC?g*MIA2=mH}a= z_S;(EQ^!LhBZD`-3Pyopn8vx>k<4Xtd(Z!r5IeM#PxTu6YZYaxJo3|z?8sTNl4iwo zS&@l9AvHyx^s4?;NTj?FYf9+-NYiB!-k;i$RolE(1CKJ=Raa>c{(h&J8ox?W*$ECd z3=)Zve=p;lN+bhq%^F3`LEySvy_KVl^lA|hzQ?IZdbYOR-LOWEdGx7U?NgI9{_fr! zcOvR$vfG}AxA5RMj!#}m{FYPWJ~CuH|1BdRilPpReJmJIzB_Hb z^zMjvzc8_P7%MmRKZtjPIuT zcqlz-i+n-t+P=@eT~sVs4HnMZmc2tBX=nykUfwa@B~@X*m)HrZ$WfYp+>Nq%*xB;< zxvYiE8FU(7F>=4rMXk*g&P|fI-zN_ZElKt60tP~;+_a}`&x?&lazNte5|t;fUVYda z7O-5BUIP>pr}ooUDJR@c7i8q*3;7xGk_?j29_1&A!5x3S$B=-6XGfJ^8p>>hG^_$q z@WAdBfYKoGRf!EGi^*~^a~Bn`TYxNsgL20fCAr<0!E@`h&;cm`)>ijL^~P~A z?M-r*AOZzYpYf!%QNG%2=o}B{~GxuZHX%fXD`dv3Wm=&eb49a15+aGAAhlVQO zh-wI;0yQ#f(Ata?R;=!@d8W42wQ>7b`R=f??OxweQJ0n4mRg7NNcdJ<*lOuoSz3L_ z8X6)zJC8O^J6Rj-o?q=KnfM#L?29?`k@Dz3sN0XinS)6D0PS|^PFlr(ueYb6V1JFo zt)&5T{Bwb8?q{xr@*)0)eNt{KnY@FT(nt$>ur09`I0mzn>+nVKgY}o^s zb}c(X#kmK+j?f458bG?GUfZBs?f4r-eW7*$DuVw3Oi4Z@Y&M1KtKwW&8p*} zHjUSoHp)R@zfi72kW^;D>(tW(=mKm0mD(cYZtX=bDRta?dQP4=QgT|bd0^QqB?{;K zywQ9TcN!Rx#26IK!}Uvr#?&`q=u3vT&E~y4i}2q22LjYzs3oKcsJWIX+vI)ZYG6gO za@(5pZ0N%`^Bf4#?|)N`uiG17;F$NZ!Y+|YDo*JN^wBEatv>>;*f4q@FQ+#UgQBHJnb$p~U12q^SkZ$2VOO&84E5X_d z{LdX2^Qzx^*gql71?9pFGHQZByi_xx^9;#COsU-a_kUgihcYc?D~$ZwfD`K9j1=#$}rP*|DixxqahS|1hp}i%b*3d3fjh3 zK!#hT)gjPz@8fx9!q)g3?sgD9-kmb55Iw#ck3L2HU-8b1O>)x@(@f0;G=}UyQW?ZT z8L_zA{L5CBme{Zfclbqiw-jigqn>Y7% z2`63ZR-{7&yW58u zmN1WYp1rxPe)QJw_N%!kbBGs1Pfz?1FIzR+2Qbo_;tRK7hdZ3V54l`aG<+rMhF-v6}tV``9|S4*10u%7=*!vz4kK%6a=R2 z;NXI=i`a2%#Q5Hr{P3_|e#870yQX*;tApYwrrr8jg}glHC;QP^oz(e}_w&72*5h4I z+8YxEmXK}fZd8UZ9QES@Orf2Gn5zD7q0K~ZO&c|_fADwd-wO~95Vasr)4H`%!{Pu- z3>Gan;f=uUSI%{ts9=Vo9_dmNv!rM@WLFC=B{wvJP6uVna~p^Gxxh!c)7mvSh>wl zM1w)08|e@?4{pF8ZP>U|uNpI8zWwVL%KalhhySRg`R3aXj|u-eC@}s@6V%RH%Y^m) zWfk;CLK9BPmTsJp0Qq1eoBoYe3RqPQ+@VP=L?-C#WLxk0%n7jGjX;GZ#N?6s7uDup zjDLzTOL@&)q+S9I(cv=w^wW1K%a21?>}mhTRaP)IQYj69OJpE?wBP$8- zjva+<39v$og!+kJ;&-F0ac5aF#7&J&B?SH=-2|V;=7P+O0~Nw1C_zgyBy51Sa+ zD2RuUtD;MKh&hadGxC>eQIVWk_p9cvpVBlu3Tp>t)S%7KcnZoMJ%WfJnkhd zJ`k=oKIiJ^JWJt!{Dp3yFAcK!XDoHUCCGrQYw4Aay+mmW$yE6W*AM*@D3*nCdU_ZT z1A8+~IW8|3T1Ytx8^PVB*X^CvUDWC-0L;#g_BNUzNRlc#PRL@L0y0usU1yr3{>9d2 zASyh?o(q09W>G#r&fs-kKQxOJ@2{Sa*yg$%p?5_{PaVJ&{~Hs#j~Gdmymi>!LXwnv zcP3+Ry{X{GhpWr0Z5Q{ZnoEy{UQwq&0Ovrf?ZWfS-Eeo6OjI)+e6601UQRdPRPEMT;WYe6{FFmtm8!kG~YFW_8D@ug*V-@#S^8E$L2C zGlx|iRXkoJ0`!Sm$hkh&)_gelWKjP}<9C>huS?+Hf4`{9ztYD{1LVc%HnhU${N-13n2v&ZP8Y5Ry?g*)WXYL5?r^pj8f?cP(=K^sAL-q zvR4f&Ce}8hmcEZApGumq)~pRv6QNKOkt-7NJ{;9(eYwvz2o#^q8XkHm();Fjr1`xT zX}$gC;K=Br;&js(JTJZrcBc^#z&U6y4_mxqm zg^?nW^|?A${uEq^scuvTUnly9S}I2WTX-iT#umxhlyb(AB$5L=^M)_d{gJF8?KdOt z?P)sdHh&Qk5h^bDI!%CTdI>g)QGoyFp|d#fCRnE6w2<+1<*R@V7EeX4vt~J$*|BY( z15PPXPrfYYGRiBUY=}KThc||cp%DxGE;0e?5BQCe9&|y`Qi(=9DwP%JjwX&gx%&wE zjpl_{O)af@8n@ve=tz^Fl!v)=U?l;`1;r7G5aol_2E_3Jug&nCRRA=>g*QuY&|qFG z`GRX1*;^)!l7_xx6=v4&{!EB&&Bq1t1zrTY27620nwk9RxByLN64=jn#2->`3ISBQ zw`pv$seB@!)L@Fg9vHk6-QKv|d`@2$kg636Qp|YRkV34TNN_U-wXHNIY$CW0d+x}e zrSk%~q|qH8p+oM?HbjS+#Vq|2Aide}y=XSKjnL(yPTz*5Hk)xz9(5Y~ryU1k);P3P z>gJGiyx_eWQJSIfhNKKd>=A?SljrB*k{Vk)VKI#3ySs7x;5V;0v>^rLly`{3z*Q+hur6WD39PjLD zCo{on8%e|8_?@*W+!ZcbmzZoBUEoXkf&p~MfON}j*?a0U$;{VyTs)jVCRe7NSb@@@ zC=R*%kKDmg@{zt&8fj?jnsTA{FIRliW)D)DS%PpchyO812SQ}l%aJfBkHypri+k$^ z&XYABHjqmavDo*^BT7%>r)Xt=gdqU^l5Lkm^O9Fp;wRHf@w_2!}<~kXu~On*#G2x?Yb=7 z^lXF_7Dc6(We!Y~BM#>eud8C{g`bc9)Hy!)+zr=pw=)Dfgib{&0^Mi|O;RNz##`=e z{?ijpn%en)q1>IBEo=o-DeJmrISU6lBdtn(AH{^ zx68f{;}tFC8-_e6phM7C_O4)TDEiqrNtMTc`E`p??a~7~6p)_obSuxKwy2(EOA#FJ$XDK$f${5J%W z-QK$dJC+wAyUaoonEk;ome>1VgKEX^=0*G7sc~@B+276(_jz}r5$T8f@qhqcSbgG= z1m^bQ_2dR5B%f1EJtHf^n79~v1Jwn_xNJ`1Sw&=%AW@(NKsgVDJRkB4&vl|Yi;h%) zz|2AdRU85!q{XC_9)gM6Dw|PpaEq4Vo-Uq44e%|9{(Y|Io*BaKEitjYpwOGcHx;ft z-ML_#SIPS&m>cvP92pBy#JWb+(x&Fat*oGeh*Ow*V5#Xyengod$_1Kw4viB5av4C_ zF`o303<;B5p`d9rYG9{*-ubJfhns4@TPQPI?gFsr!v{01Eo^C!Jy;31-bs(UPU)SR zK5pGA9QXP|)ZQ*-AgP}J7U$s~vd=Mr%Ma>A5+`w}yN^yTH%BP=(Ppprch^PDlhpe& zDi_4~*N^bhuX!GoO+|~J_qk*kV{XEnYf_~T>M|D4Pk4|1Y~hvUgqw6F&us3WS1Epj z>+KPGsXu-=u5y}U7(X~e^zr2{CDD}Qb=pg{dC5(*DG#^`#EIW8@dPT8xpBKuEh=df zu-m3eg3ec=&Wkz{xPU=>Una%@$ zY)bm|xy$8AX8GfAqwynuW5rLD1i)tOI+=JMEtlSpSxRF@)9G|(CTX)0A*9u`;)wV%L3bH40%E?AERQ*)xR7Z0jFJ6nB*w>Gpr zS6S+xy}v!>qy!{S|6OnKeb#)wKSqQgC*3!lx6y0vFFGE*jsJ(Sw~T7~f#1KkQ3HvM zP8kD{Q0cA#BLxAakxr$hd-P}!kd_pXmhP66Qo1DsY3b(P?|1J1lmEHzbH0!FIcE=c z_Wr!%x?UGJM(4nIv-$MO*>vx}iCZtXV*jU_88j&Y+Wv0Iu5CFPbexZp-0JG7`hP|{ zKJ&FdTK2QY%$i~&-v2al6OMHHtGJE+jV|-C0(4fMKi}cjlEXvVrnb|;U_c#7o_Ne!rr9%e6ksacREPRWDtD?CN*Z6BHD1!jm^G456dG$^9Qm6(8K~;KX(f9N6S6hVBZKhL=-X2Y&SFRyk3Fe?&sMmp^ zAuB24?^sG@d!3&W*~0^NeraKk8L^HSY-hfgmBu}t9=qt%j5`?h{bWs`&)1jluO)_; znTcCA9aO?1E;@D;?+*P$tmRJCoatpMV?(Fd_aZ~((?ZMP=lZQJE%I+en$sw3P9ndseK_0sb#Q6Qw61Qp3{*zQ|NWl7;`he%!;t8OKBt_h4qCfk5W@l2B4l_} zPe?^rqk}B*i(ozYTNc?(FY+r#C77H^|L{)f*GJjshy_8sb=dyhI6n<2Tz7+%($;ND zpij)vk~^&Gt-QD`f$xGtek`suHWM-g(D)+HNM!OQNp>=fs82A=lMAWK*pn~9Ck$uXsAr!>@iJt>bBI^t?c|QNt zHmPz6cZ)WOj|ICk{9fe9#65L!3B=PgMd<|90GC~RbI}E_J{#b66$vw#(&dr0CjLH< zllo3GEyyg86_JR@GI++&r4ua6)p<_R4#WpWRZ50QWtbn1QcDiYJlZj{J^6DHw{Q1w za>!};bzC&oa9`2nWXZ=vgwuXI-2Iz4;mX%xqm4~jokK@r#gML#{CA110Q#LT5`Om^ ztU%4wIrk;a`0`4ra|NJrnveu)G`di(uGn9-j7@_W;D zM8n9+(D2_aRik?vIEN#B&6>yX#QDm=@kFIyX-x;6nJ}5O1t`Mq1sWwus7(G7a@r-cRge<#k3b?oudkA=FIvGRoFd)HmIM4ha2 z5ecZeSvCo^V>5CDm@)g=?PNR0OGwGzhXC6Cz*A^@1%S0FQbIJ}Oc`#Jw?c36gOHR6 zOT8;^4b^~8$=8btabl0%_Kz7`D*R`Mv%4Yjtw`@L?YA`HKF$zbBqGo!K?@1NEwwHV zJPX(|%}6j)=`+8Z57uc&nhsk2B#kicz=mawo)U;*{;kyee`{>E`orlL=M-W#V=%CKq;b!;Tn2flQOEwi4Uz6$F%gYw9;cLw|~7Y_Ef`XjI3 zo3qHfB3ks_dR4pU&X2Y6Q=M_AXNwU)RS zDa;K(0AGMrsPe7%;!D-~7cz!RZVi;XJ%?COwsj4QXf|*T04PiGrMH54Mzp(xEODy{ z)9BqTe~*Pq55JKjuII5<>$sFCDfnwI@_BK7Vk6VU!yphJ3>20i^1Pii7d6eyB$GT6 z0~;bu&o!bQq*FzZIzjO7#(dS+@NuF+f?ykaw)N8AR-r=J~iK(<8aCOEv*LmzrP;kUh7)H3TpJRf1n*_ z>iMboIaondmoO)z@oC_0X!z8V+oA5yWjUHJuFl&b?bat_jj zp5IR$C3?5&#}X`~OIXOma*1-tf3LEwQu%KY%|Zj=zpvQi^}_Q^*l^PY&AvgN8JPU$ z^Q~Fv;2p&LVDo4;pau0RATU(S7*#?KK%`4Ifh?mNozPi$ z_M8ZO7CzV%)l1dUSqXHzYBHvt+h9;r5o0~=yNm>ZN)SD>1~_fSyz7Y zV^xpgeTnZ@>c6= z`D_2cW@OaI_c*cp68{f8&j0>$$zS*XXaQnD{DtG3DRC{ouqKPtK-y77kOuET5T>?K zmE_zpQ)#KkkN3qtQ8XU5GE0z7+~;Z^f0Tn=*mXhvQ4tUY3BC@{!8|H{CrwNd3GYVR zyWF?b8~90ZHQXl+9y4~2EO=Vze5P5-&yMlACdFl&=5TTa}e;LV|;=#N|vgek(zR?@4)2aEj)alp6htj*}6xBG@Gd# z;mXRUzvW`O7EY3??3=D|VG00ctUVQ^7#n}c>XtvJ_kRQpx2=rg!a&Er2HGB5ha7#6 z9QbmJk3xnN1Z1vPEtj2Y3w*vyn)oxez6s)l{hY73I;+t0RZ^@N$`*<-uz7P}wo{kc zek7t;NgknyWFfA9PoI=*2`?IL;lxa7P2)X+C2Y!Pk;tee^m8NsYZh@ z*vH>y>H1bAVv>ttn32cbaKV@NMaBJy*ddY)Al>DIoQQ`IBFNjG{%vExXtlq5u3eI$ zYPXF%c_WpvpUwxzMJsl`*N;)ST5x=?MLEywvIWGQNDWNDCG?iqZhr1U7PMTYSK{1M z&q`uw7^z4@-zWOIsIeh!i>S|=pJ<2;6*zUgan>y9l~MXpahUp9^6O}7EW2L`bMqjc zz*<~=P8xaRm8O$x9dbIli9_8p{pvrbUUiZI4+0v_yfLchLxzQJ3<=iQ=H9CB1gPjg zW2-!kK1n}{X(XY--vA84-v?j=Jc1exG(RMXD=$4}=3vqmu@krS1OkyV9Ns{7+>8Y7 zZ@5VmjLBl+Pk$C@rscQR;mBdz^9$=d%P08A$@3*|rl0d}`VwpLg=mw&aRIvwJBmhE zEaum%H@14u4}-@>k)KrcxSE}|ehAIYnc+!3&4rO`KewJ3E)}cO0N3h!>T_X9c<(s5 z(ymGz?HRn(yx=bs!$qT9K(<&r@+LI|xfH#Y@$V1YHyX}+$824yY+b|wv zegttme>Wj1DSzWj{FlDuYu9usAAf!Jle;;6*Cum5J_AK?y8%6owoT-n zj~vgEm0)4Rr8wm4Lu^jNWhX%S#j8(eYxmMFN6hPk2Y88t2j=kR)FdI+C94lJJ$_Ip zFc*~oJ`e6z?DX>9-$?DFwrAH$uLzAH7^W`lMW++?F_s!;i#jd&pWr-bR#Hq~$t?Do|&D_4Qpyn0uRq!Zfv`_uB4$ z|1bWgWS)_(ro}^kUF>H4*NGJuZcgSO>(LJoHS>t12wfCK!Zglow5ovRo7iLydCb;h zlo#8!&fxPFkL$QdWvPKd>2_MniTuWP#u!@GRt~f7c#rIxJnYO)0(TO3NRW^5EJPK^ zR~T3mZo+Xix~9aMB#tdEuez@8r#T(##o;yec!w3QKDW;K9@&U>v{60H_HX0jem+*fnQM&90+gasa zbvd+3jiwpa>h)Q1cFJ8DTiJDY3gfwL4SfA3^&fU5d20xQ_Vb4Wj|Vms#cS3TMU$gx zPT`_d^6wBpF`GUM|B1FMTQRq~J}}Fg`136Hq&BVur-mi8GWPxL-#KVuQ#kG9Q!4~r z5D#{F_)oGak|v z>7$g0S_Sp$qiFur<2qWK;3h?ST28KopN}2=u?T%<1%%QI;t;3P8%r_#Zrh|5XgS+zj_~Yj$B!Ak*7@r-qyFA(rGu@)x|4JlN_@cov zi|jOE;?G|jO-b!vOOd<|(kLW=U|fewH3tax^t$abz#Lo0s&mwUv2HcINphArGLPN9{NsV(5lAoXQDbb-<~vfAh1a`?Ff2ALf&RFo*r|& zcs?T?lpJ-IJA&VJ1Rya#9MeGxZsAaEVc$`Iky6-U)ahwCBGMXEUY}Z3CKqw&F@n((~|9fRv}TGkdT@WX|tUOXK^u0f+yscwKINl0us&Dc*Jv8MgQ( z0!qejIB8M-N7EN~16enY531!g*-yNiz%)S*=WDl@9imbamruLI!e1u1>Yl4_?ldKl zqv2;i<>?*pKnf5X5Dq+67Kb0=%(6D(V)^D7mNZ)MY%I$3Jh{5vTVAK&Q_SrkAnCLk z515DBBpZQDPDx}e?h^}8r8}`kWxO;5Kw2MO8Du|<)f@V0!E)8G^QdHuv>z;Jkwlbv zMs^hH{QBk(rJ_@wd`^% z;bvcSp-?Qph?vwQZk`}abraIFlk4r8QBY%RKGU;GveQUP0}e@IEi81L9)DyUkIL5B zda_cId_>u3rz>iT~|gSK;18>ngT9PKcx%om)WDquVzH0a2fWK4Wp4Qst4X)HwLGRdSOX(dl z1SnTL!-A)CwDY@O>}Eat2V66A?0k=#B9gxECvN*e{A!5jv$*r+T7$r2$F_*erZH3v zAt_eg{%Sh$gnKZE3x!Efk+ZYsLS18!q+@iwUXMN!UL8=LHiifXvdgPmhC%d0s&HLH z(#hG}`v;2rQiaN%1=X<~jC9J&>c>^p4n(rEARFsLzY>(a8XM0Go*T@yrWj!Bod(fB z#2zt`=x{;HWa|wBAK^3tD8SziU~b`!2PR{5uGY4V`8e}Wt&15S_l(*0*30hc?=8{< zN0COE(=Gh!gH~%(t%nNxNPf2Wd-pMv z!Q&=b$KyG+pQIC_5Iy5)UpkDbcsxtoAl^Qk%rFV|P&FQ!rquW&*CB5zWW@9&FAsmY z7pYXmUQB>cNp(=InHzO5s|sG=gjA)SPM-s#F0PM$Tji%aj0V0KB?|Ib@|JiA>OG=J+`LHhazDY7H!mMi!w4@P zT&6s4=uT>aw=(QKH{X5O_y3Q+^NRnSJjrx$0%Oos6PA-x*=-Az`yJPRF7CIyc&>Mm zu3MImqIo{glwNUtrkA|(ski--CbmUsTMdYKRbeU5xQVuW@T4 zD%%~{(4-Y?qC!(rTqRa?K-V|>w8};Vq{)E!)U{=s<_n#g)=PGHdb`~s{9l=^cE{rM z$x8H^0s1Xw{B4nv2_C@T8Mfv}mm;Jn;h(_7Q_DuVHH7(DS!I)=qFW#&2*rlY%~#*h zFtY2|TK^?7s3)1_EnqwXjWsS)6Q{+Lz_~I#nJHOg>UJLzaX*WrZW7NkvSIYiZz1(P zc8h-cIDb}2J$axtj16A~o{-mov4ey}`6<9zJOStl5rX=OrL||~i47A59#S<$29Y_y zT-)Ypc~Fc-$aPFCI1DG3j<*!li3Lk6P5$bx{jwoj%>%@)YC>8SWQH>>Vg{CTaj*Jr zuJSC)e^h8!$-`G%t42fcYO$1DOo5{k#2%E8#wNwUAE< z$b2FY;LBZec2)bAc!f7H^RU@EAFq;4RP2%GomPy24=tnkv9LH{F-LbzVW&&Yf};UM z@f`wt!Yh6vX9)Z*mY1y-8R`40_~2I4%{rX+oB0r;QUvm>bih zZ3?|_eHd8p@{39Qh3X@SeFY-unO%6p#w)J@aX6&KEaqPt?;n+oek-g0-IgQv6)J{0 zCbdxRotLFbF3#hnFA*q%Y^5u)zt)$gpb13$^zJ;Z3A!8~Hp0Ffg@^e|CE7rz2-@GR zX3&x{luXf-%p$%TxyHx{XXA zF$k-H?y?sue^A1;vOQ2ZO~x1HNZa_Gz@aHf7!M!Ri=u|-oq$V;yRO@>o2qjF(FX_2 z3-cfy5k)=-;7zP_ItGc2-GYk=VBQ?CVzyYI0Lbgsfp>A?h^uQ!2+&8H`GxrLKkNyt zrN1=r26ZtJjCWLvR=p5G*jpicHvc?zj+#59$^o)VX(mxspxp=R`_}FWX4--7NlS zU6yUjTT3lsz6odE5$33E>JTXz*cs+>4==_VmrM8*@s^+7QZ#niy4^5e%&R)YP>O*d zJwVg9jBx&8nJt$bkA@r&F+{k(-1KIDv0dV|{K?v0s~r7?V)v@}kQ>cu4^>{gH0~3$ z$3CB93s)j94X0a%k?%dOwsKqIW`4H1a>J+q2@g1)PRiwo=kKvAYJ-*L^t)Sv(Q1Hu7YN?20_JyK|#IlJXN`B|{)) zo_BS4iI`hxX)!tI#V=z@2v^W2@JF=|N3}8qi*-cvzn&WEW=fb{uXCY{Aky!feHK)# zkE^HMZlNcM9f;b?ZDU(2>_@WO7%rSY8p{g!~2DhA}zZX zlCRn-*yc$>X~&kPz5={UuCHr;>#CDL0EdZmuWCg=5)p%j$iEx+%&up z7VAz>e3r=Lk!siXS7B#S4QAUaJ|Aj{zI<@8?cU6yX)Y@2<%l{`fw6vPA!S~yK1udE z;}oSU&)e;!U$PN=2h1_bu^D~EI?Q@`9ML^$|@B zfRvl(#g9|dddn|4yhJ}2U*`VAV^HGkg+R)JYZ(@sLygOz26*^)Ni=?_Sya`|YOD^p zh@qB)r`h9CzK{{ntRtWg0^K1lVS}0@j)slQo&=_8u{o;7$8e(KoK6JRnx%CGX0Mm= za!L?(63x~{+;iC9qN+wn-jsOw%lx;1-ad=j)$qO zQ+zqme@pW>tmau;t3d_ymj18P;%VfTaVXXw4gVc~nGvkQ73tl#a%v!5`J4NsVD`(B{4+EhJVU3E~t1gW3fE%^7Jh%Q^te_ z_)13543jZ7p8KGbL6-88hMbCb`;TKMEcpEUKhvfj(ux;Ejf(*{~6O>FK4X8i2cW!Uaa=qY^!RGYvQZ^e;2uX$Ma>D>H59a z!<&E=ecOhjrlpq3(lEJCir-i?2%pDSW3g-JSddb`3c((Pxf802^Tk_a<_477SIGgq+RXv;;Lccn`Ir-6^tB*KS# zKFduvdu``UKKp}?5C4~RE}(EiYKKUXcjKLxHj8}x7b5oy9Oe9?fxjqe?25u0j=)|wUC`6y> z#o4yo2t^YhOa^UEkz_$t5Pfjms&`4f^mnjeh=QVUd{g5~WQ&Jwx@Mm+qqi*qFE|Agy{t0i`t;`d zSCx^V8W7Yg!Nlxnb(>wD>zP%VUN!EnimS%L=L&+Aa+PRpbKb!OYvtPMJaV~mUEP1n z(fG4;1Bj%5k3zHj#2{l?GhZIpCV$?s`%uP$jbA@gR!g=8^o%U%ZL#_pUX)F>&Pge^ zH1*wd&#-XoiKZ!xsnb!k>Yqw7n2wT((zTjE$8Tmn4#P^fuAdE60Cwt`ErhDf;I;Xj z$Gtl4q2+6O{p)MD8IAf(NRc)1%H=0HEwXgt%lKD3ov6An4i~3SF=CdW0k#m;xN)KA zl4*yQ!p3)cV=s$2=xmeHaNiMW6O_ptjM|INMm-mP1Ho4BLbu5=Jomr036-th*3V(1 z{uQY{6#_S>mY6rS$FrL!)M4tc;qFpat}+{_U}0M}r=(l_?3(%>&mNQ)$xZLHt0;?H z1#t^^&xKX(fX67K`*%SBlN6Wgbe`HroKds7XE{bjLhR-AA3W2 z1(|q{Rqb#Irkl3yD8IkwO^9a?Ln5fV!v7h_fWBebHGrhM8W`3-U`Y)AE~USm%kJ{{ zG*;!=j5|d^c?O-&7lE_G2nzl(X?&JK061~kABR@`v#Z->;!^~ZGUpLF?Na)G3pH@V zNPw*nF^87rUCKS=Pk!u+ENTUB(|3DEH52H%5;`*6x&zo{k|<@M{tMEoycP;?oUA%E zAcD`|F39LdjqB4dSLVjPZ-hX7@Gy!PwfBm+7X4>zW!H3HErBw&zh7u~_H|#-ZtfEx zLei+XyG^QLY{)Gj<%R-9G~Un<;%(fxzIqimVJ9t`H|GkP-WOs27V?rV`7hDCI&t5v z8j=C}Nl{L@uQp;(d*!LGJe~v*)YcU|&5_iVZ=$MOWS9Z^G({$h{@U|uo>C!Txoz>;)352iKds>aeA8Fca@ zjGFt^PZM~kMz;0*Ts$0Ug38-_dXTa;`t74gbM=~E!0(x!fDEcckD9z|stBX!!MrC1 zmI5~<)n(TKH|}@FqEg}%b7E;XbT6XA_1!=HWpg0-Zp-6(tL}B+a43__B6HJR8xNT% zu8vIX~=q}PjtL(ef6aOU3+l}ouBC4^+_xeWD0f(zcrz?}J zH$O|yGtet7ZWmdV{+Dfzx0Dr?4QnxH2Ptoe{-faJfBMIwI2{UU=gx_<$n^F?-js=O1hC^~iZEd2gmJkzan~q^Xr> z$3UpXpf*u*>L3LSc>?+$waKR3osrS22L>zut;BPokfU+;3}cT9A3-bjE(lXo#n)vE z3|*2b03Ms6nxODMaufMMH*zT$#4M5}zER&!aKwF^#Bqf^_En9qKU?8|DIptqOE5Cu ztcLL|3h^0A2NNZku^ay^QElpXkBFF6o9~dKfrB@oa-AyJY=V}q3vNc~W{(6#s0pnm z=7kTvi7+AVduLD0xOsSN17GK$1^kuI>%%~tz97d=e>UR(O( zxX-u$qXp2xxh+(%p}+hT2tkf0CvbXCiu=U3-0zHx8+2PnPu<3ZcdLMM43zP4?HbZQ zNQ;pFWf#?=2nmk^wO=RGGfJMuPZ)I9v?I(3AmF#L6zXO;P#`Fn2vI{i;Z;4%$%?A} zC6c6p63kJFIWBsvpyZ3VSS2{9mKKx>(v9oHD#l7;IO6MnNj{Np5B`N81F{j(pBYuq z#Us>MHyGj3r$$br;PJFrZXhBQG{1{=^hiZbeFK<=TgzmjoI{RT%tAu&?|HiPWmX<( zM`66B-JD^rln!%UuBwTaW7Qr@T}x ze7XAvYy7t94t@ye`V2?-O-?j`L7GWsN(4K9fNfN|OrB4oi^K`U!LP_u;0BqIeH+ra zq>~A@;78+s8#lku?VBzL0YKsoNl?Og4R+(%&!Op$dkNmAaMyr()}KT!@NM+-#ZSaD z$z*m?VX?BBxPJ`32Kx7)aDTLhumwpN$YutMe1=J7bwAf{w0ea9_y_18v8g#vHk3GE zN0L$+^RcmGLe^*kg9_kFUm+YI6Jp@HsuU)yJ9{F~Z5h7a;!$PP(78#m)5Bi-ctnMj zXiK7T5^R*?iTH#=PH;qgq^goDZ!)N4piHi8d~Upjom0mA?5DgJiXX5XD2KISkC7_ts+2){^J&y=KCGl+ z(PSdvQ&AdMkAaXpFtszaV1R}FjkM7Z{};n2*?0r3@9~nRjmxbSjGY}W>l|8cv*pZc zUMkg~u_5>|T1Wpxu^x13PDTHSlzeRw+!p?tXyR+>>#`0bIN^vZ7cf~c0 zjc@PLiS89WXHJlYKvR>rvP0vvc;#+(cdd&6xAJ2`C=N<41UnC`?(D1j?#*IFQFwp^ zXGw<)GQ5(GJE4*0`p?5&#-=0E`8kpr^vOBX$UQuSJ2DgY@!L_;NHxB=?l2v-b9C7V(|D+)TcB`%L`nbk)9If`Vwp({u!~44piu#VL?O z@e<52+YW)oj(+@FI6YT91Y%ec=78p7?*MgyVS;%rHWT7vCzCJiANzdZP3ox^`6;)L zUMx)Ajj~IxT&jPvauFHfM;MD6;OywMWz14YsGqRgP-jrC%$-AGyWv4>Ld;r4Mb~I; zJ4&nuzcPu*3TO!U@Yr5F;N_H@W?HN%xV_jh>yhTb)8zdOT{PY4RL_c!+EfYem&n77 zl+~$2M@w`(H_ce~| zCs}rkVF(?)l2&A&B;U1xhYVz*hklWzdEU<30s0Q0LN&v=u~zPwBHR{-R0;fSP5kWw$DmmLhjNP%=}ZJfDJ@7v zB$wyM?r+OS0s`t}L^i-$)XSLJi-7}7{ZKP40l{Rdh;!*6^%A#QSPeENTy&S4lz5nT=I)|_)4)KA?G5l;7CsukCy}UEK6McLEjfCZ*m)OPj*}4Hh_3qU zyfp&KzL}SJCIj3BcI=Hy>E#Ja;!@%0#uPOf4nZfpXG{C+uNM zCC!NryZ{#9Ltkg>q+Y}sO{B$YJwx9^}Gt$ls6;IbmJ z88)4$c$ur_xvaNRDb&7H#h4kZ@ePR^2&t0tIAoPl15-K~qLu`=N5^CWt|s98QT;4Z zz7eO{Jg2^P^6y+8ssY#&&6;T%iArI#kQP0XJMPP@_tagrEymr{d&^$g-I4E-Zr;76 zIP_krq@=>HCgW1d^H`ES+&kp6rr?zH8*#6BeI2Ez@gQebcUB+ZY98P&{f};V=6LIX z&tv&%8%&jS|J<}PFxEh#BI5Jmy2HU^9oh@ohLuvfmp8kWTVvHNM!?P~i~B!=f9V3s z%UC;*y_>tl>PH7NlGpb_4|EB45fA2Z5=wyopONQoL&grH(Rg=v%w9`p^*Fzn=q(o9(>d}`qaP^Z91PwLB z;g3F3TkcS>Nx~!p-5XxJFcM)XOB3CmUoa=v$r#JFfEaX%xA$o!)zqmYcj=gKw@CEJu-y8n)Lb4-KQ686*KheIqQ zP-AgCY~O5-E4$gh?wQ}#EKvwIw;h#f1GHz_RF@y~tBo5=(l$rokyy6q$M-TC>0hsh zyZL#VSm7Z}n7h)qgN`eP3yUsvOa#Hs;@Q0Ww3VX}YITB00qi{4l|MY5&*8nwOt@4k zMlGxPP~r;i4b(2E7|%qaN`kTK_Wq*hPrhUJm|2VGx1^L(xBc!Bu)!qZgW-;&3P?6)Oy4@V$V+b*-b z-+#juE;=sTN^4fGB1JxPhal2_3&vDfIf^5Wy1hw*qe>RUGf2+o7QBs2=gT97w%R_w zB3}~KZgk7bC3o_t_?OTe{E9!7=tlvHg8)JecTPfBQspFP~m%jmNaM@NDu}f zVozB6vwIGyq77x2%g>%-x+FeSO@VFw#!@FI+zJf1JbUbM$o8XWFToOC3OEbP^O<+-oh*?V?iTJ4HDZFz zThgG*kl!ha*nO_^x&8obpoG184%*9cO7&=?!J7MoJuHf-pkW|xYy1}hfXP83tmye| zjQ~MDB9WGs^6XvA&NO-XD9jHT;2iqfH`Lb~J1Ee&972bO|Cj@-SD{xmDjQ?saXx&c z0G81`r5(lJ+oV;YsScjgW!{`fBm?)#U)qy&%)+J8fiG4!8pD>(xmjhX2q1xj6sB-uDfQ(%r9>#D|7*-x8wo z%UZnMRnpmCQzFWAEhEjrUSG=h3c=mmlI9-MWFW;Q^#c}3Dt*UeU-!AY+qWQ`oYLr% z^#zKrbBltUl#XKE{WCnD8&Z$+4O~)p{K>O8WvE*AhwQn8My?Wt?HaxuO1I<5;LU2A zWPn>9k8=syaDC2`@R=msVw8-}UHBPiw48q@HD)=^0O!eA7UijV`zr*zd{s4P_bd=u zL7_~usYD61@ORav&s^pZ9G*hlMEGD%3{QjGkD7!&dAxt32+6A1zu^gCtm17*^|~G+ zddg8JXgm^mJq$mFdA2MXD(qpagSW#LyzJi}3>AbdjnEqD@7ED3-(V2dKktaR&pTvi zN*8Tw83P_$``~u=ZJZ=7INq23y82gH^*Yb!x{grYYVvke-~)@O?udEf7=(6WJIvzNR}V2S6=L1t+d?y*$NQg+Ubbac{!Fu zbvE1QzRN(E06cOZHOAw2t5Xs338#M&;IP-=sH$dN2ceWO*H7$O zmg>r;uC;l{!*y;#^1CX=Iz}#J-fpNFA!*xX?o@M0?j5$fi`Ji${9KP^01yo1;1fJu z?p;mG)H3QtCBv=Y%z1j!W(8*2_BF~a{%YCd z&kYZ}g%pprQ{vRvtfws{e=L-GCGZ8xe^tfSb%1}Kr!AjGU{8wUZC*91N*-`DQO7hu zU`7Cmd3iz{cu)i7PrObS+u;}_ficTL`XnB7n}VAw|4^l}EGRAjIe}#okL(4=ScSN;=GLgEit5Re zz!|S&=Qbp(XP8dMPw1IEAy`S4oiK1#sDVJ0jzQ`>V8B#QRs%vaUyDAlOdMMScb>Nw z51SGA8>kNCutI2d3Ff3LsdA`m!l-TDbg2+`rpZT3Tq~q(b5U_CJaN_P{9N9Z7L@i1 z`WB(Y$Sw-p`uZl*zJs+;*nL4X{Q2Z zI_lBVtGO7JiF!ye;kRe2Suj%dPuP^>1=YAKVKDjQQR;m!R8w|c-fnO=v)u9$ie!x+xR)n_1x5>H zK|X4jQbf)qs{{K^ss;q7iq8KbfPo%N}6 z@gai{%*5yX)aJtn>)+8*3}Gi1AuN^4;(xy@Q?kDbG}$xjdjC4;rR-0ly%+UP*0v#T zc+Q^%)F}H8{V}G`3$t+RqT#=(x#RNdG?T7IM+^x*pB zY9cpiBA>hI9Y|92&2d$0@M?(W=dK@|#XkT5Gq9K}em?m=RvwYMe4whN{;VH~M_s5Z zsRcToiGx+HIXyZ+bb_fd7B0Y_@;ufirZ7f5(rFjD-Zo~f>xdI&Ngq1NN5a~@)Iu9@ z&q?EdkMXYX_35iZt@$iG3I`5<^bMIo5QGDA#Y^t;bWA`PE87SxKQ|Q`3YF+O4?5FA zgp)ecp%C0!M5jQ#wEWZ!wCPiGFA_(rBwWo3Xowt|35^~l#i3ZL$Di;?{Q%d1^SD?f zM;+GF?|sUzgX}^KNIL#P4IW8k0}@s%_1P+NG;v9TLcmr;+9FAVIVwO^vZ|8SHFz}} zGZU|pycvx%O(;9_n~_`<;J={Xb`j_Ke3$isl5D0{0%ltf(ePQHfz{QS=X>8tyNFhm zWf{oPUxG>mJk22F%xIIUpmDdVUEGp!)MGV0LYZh{s|qMC-a20E1=V4Gy0!W<2=}Nq zb}4UfdFX2#O>IP8xM2f0OMxDKTNwTmw~SEu7Xo5|jrqPoR2hHjC?5h|Z;gSDOjJB; zWlrT#P^S?VN?j_^n52;*e=DJD=CzEon|HErQsaBQAX-`xIX7W4^mYG}^=4IjGbbtg zY0S3SPZSGVzKMZ}eiw>{DIuGiW}R#E^H0i3A(3$@$Oavk39k@G)jmz-w&2 z!GtlA;(5`&`h({^d;?5*{B znL>aLHWyotv+ZP#c#%@tn}2kqZ=&!9PkiwD6$EvjDI=?&y@}c^Iawa2ZpTK`G%UAD zr7cO6w~aR1x0QXCwC$a%%D6$Sx1!sgh!~}bk2y;|ylrh1Uw$1JxO(j(<+=i!R##s6 z-v4q50MOpqe^%+Q$KJC{Bt`ve5JQ-;OxeXYGyeSTM?xy1n^vE3Gk^&HQJuR1%%Gn^*SmR!>ce z45O;@Y4Cp$XcU$6As@t%4~V3yi_6GRHQ!HkCneZuy8T+k=}&-!=B!<&zn-U``L&Me zWOsDZ{%*KoF~iFl<~x2lQa$LP9UdiQ9B&QFM2x%Ly@BOdDTf$pM8jjkel}L}50%dz z@+BVW%Ho_KZ&i3lwiSF66FtqV{Z}Nj3i;EmLK0=i8?kWGUv#xMO9pM8YT_UvZYWS} zb;IpS3_-vK@ds|lH@eQTF_>-?4LWGtL%n(aS{iUD+tJK_w+1(s@-4VN!He75%zv8L z9DT9UD%9k+t3C3AkX!p#k7!b8#0#^N?SH4Md>7MR6(Q6ER&Q1=OSuU5r^Mjh9DFR2 zlf=oJ_hWne?R(Dzm&Ydt>oEy9CpPn*)ze5<5; zy?eU?GmXA)w=O;NL5B+f=x%(B(nOf zAyifG;D6qP2FvzsNu~VG4=2_s1?S@%KE;$Y-vTFo9pO~Saxva1U3gp=tyiDAd{>f) z&8HrE3KXmQ49X9MB#8h;ps-PC(uAD~o^<04z+LGs{lK=_ywtJZIt)8{z$|Dg&IBGc znZ_iBvuH?-2K%z$Yrwh^I0T4>zaTmNcqHgM3sCX+xMXjOP;goa4GW5HK@bCE9kml< zj%MbjU@Lrz!0zUTxk{h~SU^8$yNDqQsCe#O05mpt%?nIM~jqxlX&)3sP)8f)wHbv2!m#~fx}JdaRSMw3+y zB2?CIY=dWsi&y{6Rc6A5sSAM91i|KSn?X#Z*ZnUcylA4Ma=II|1NpxiC6UPFWsF@T zg(59S@-xaUb`|71( zJEbd3%@=K&+5JF!y{X4w7+|vFm93^W%`tXk;{(ZkPF!Rw6N1e#YXQOV3iV%*MEd^_ z_>Xkq+sQlpJ~}K}tddX#pt(l#-TC>28pg z?uT=p^S?Pa=QlUs%emXH{aJgh_j*?p>E;)_gbjZ_a{_#RuN~EJzFU~)vl@2IPM?g$ z3e*wo&9M<=v1a~RPNK{wmhZ2J{#J#m&sK>7SOSb+e;jfdAakHf{V+gxV0ae)1g1xs z?Cap`@x6zv9ZLF$J_0I~*%boNPWHe4<}!4=-S3zwVI&ba>bd#a$So8b0E`#Cs38=6 z7BArV>YUfK*l?wbS6Uvd4QZXdlRemb=%;un(Wt*Pd0G%8+P7nBmRsO{o76O^eEpJ{ zl(eP6rOTbtgDYfVDw_I*$MNDO`Ct_9G1VnCLSc~7Er;Rs+>5Ga3pda_{&FhSBxE4Isr4gu~Y(dS3e&5f-eCp=? zE|XZHtWd=;sFFM>8H)6}noZlvj3Z?9xN=JEZca$`sN`xho83*;BJ2~*pq$4D*WkO7 z_Sw{w;GNoB0}|$^{*}*?5NnRweAsIgibMf-%=aU&26uNV*m{=|=6dhP4aOokKtRO;$kf^^Z5xKU9O2&i= zun#He$}QK;tLT%vefk`5sF9xca+{q2h43YD!$PBwxx&Ki3(eT&9>LFTcnmDx6?NM@ zqMO0u_34n1n)#u%B)@sdH?j;Z_~lf{R6M;M4 zy-md-VH6Ev#J7l@Bp-%CjnRw5l^=+9-%uBznTj0LuSYnw+%s?>2o$8 zeIhpwg^_q zc_SWO(yvh{@Ad|$O@V2L+cJ)7$Po$Rl=1hQ$L&slMq@oS9{x)YJjtekW+zZ2+p+*^ zpkir1Iuy5|-LVJBF~M8UJH#;Y4VF}`>9mpxPuEx;ZPf!Ez?2+e=w*wjVFRe$Ry}IU zw`E^N5V_Thj*T#?;jaCy?!QN&(rN~Vz~gJd6x1?{c)PmT=VjsLf2-!$r5qm=$M_W= z(ZC{6+(A$`?X;igU;?bQL5BFgh*m6T>u5te0`dJ69b0I(zC}FZouedfHX@Mq!9elvCE* zUMB6-JK9oNCB11`n3@fzloe|6bmsUW|A28g%tNqap?^_GW$*a;9IerXx?*HxBO8tR zPb+JZ%pFK_J;@)U#H7|bR&qI2mN)((OaNulAAdB~rR5B*BRb^>-m7o^%u4qVZzA|y zFClJ7O-hfnMaS~^2L_G=Q~o|^6z8)x&K5VGxBnz=thmUb$k^>U@2BD$|Lk?XW;0FG zT!5su{F5ZiTBrOOL7z~`lACMots2?eoaCRXsMAufV2r&}wPg1Csk%}uUBuEv!$08> zgYCJ#91qSfz$viucK!aPe+shg`pwph_{Zhnl6l5fjlA#Uwr?&fs4vR9U|7lMRN3!D#+Ec=OwtyV*< zly%2z!J(pK>Ghuk3wo&DlhV?kDE0B9d20y0r3JDRWbqy@jV4;aZq@vrmDy|Kc98#9 zk9K`JoF*%q^WSC9jlUjzGrfCTX(1A+kA z##jl1!;@J4Z%fb!Ni^yyv9CsG2KgR+2#S_SERRljqAusFp5cy3ra#kTz)vFs@*zkI zGhS^Zt-4Q^Kh!9C`y^r^P@Ch_=lp?(Ez3p+k%ydqEF7PCkFeHnEfe(8*0GFUKun-A zpqqVlzF4i|3-pv9T;RZi$5g?IAiE}Is8+iq%xdIOvgKf`&muxluag^tB3OTE0C1u^ z;<^cETe$Xr$4>VsAU<38W<%2UNZYjga6>$_Fn+56v-G>7e557woWJ?XF@{9qig@tT zN2y=O6#k2Oeja$%gnyOrxO1v87A37JkdaowRo_>Iq^Qb0&;(Heb53IbC}`T!OH0-r zcMyjayvAhi*DP1(RZPqR)#65=uxgt05i+|?FueCFW!=Jh$G-iTkO%j}gXb2B^Bu?r z?#NP{HTtnfVLpxxD&|lS%tn5vD4$02Vsq#0z|yF~x)h>dp{Rmr!jEhn@D_O~U358n zvYbR91?dB#m;^F`-2ruy>Nm^l0$K>x@6`_vO_G0%1jU<)>!gOV1KEgvc{SiW0#a}y z_`11UOgPZvup(25PHO@(V?I5Rnvi+O#M9UZNqh&pYqY?W=rA-~i{A3A!CybTZ!* z@aE-`FxLk+k@KVoV}AH2*39^PPt9B8}aK4lCnubknIzs#_2SSiA~4HyXO@cmQiB zSMvD#+~4i~yZP7APr{{yIyuet%2_J=WX!SaBn|%i_RryH4KggmpdiWZ@ZICLBG-mVA0CRo zJD;8_d^s=KZVj^azugJ=c5xsB`7fbt*DG%2$2bxZ&B%y??lK={QAN+!U|W#kgq`8+ z3^?Eezl5%inGVKW>0bztpWg0!>}?2rlDHVWpL+1Ilot$UPMTFTsQHp2;TaW)r=!hO(2Mr;;C8g_!T(7^>gX zkczv>21RVXVR4SA!F0_~SelN*mNoOS;@8!oh?k)Mid%{H_12YcA1!hl9#xQzIDli| ztLwu~cazP=x3!9Jgc;=Qbm#+EgFY6yX~15f2%-#4B!gQXX-k>=Ke4=gw0fQ1b$+lu z)O3LV+2>fXQRfZ>=y~_9Z)LElXU#UZ`qC{`RlU&0OGkF69d4Ph#JN1Co7mUaHs^c2 zH*NDRfZ>Y1RDJQ~m&QN+8H@%$ygJv9+}b-voa-J&3NgKfhe@3cFI_Sll99a6Bkq9>KT{28(`bJ>t64u*$yqUVwcy z>+X$vP9am(C{5N^f64wI-S7qNLzzPMf?q#$!g7B00sxe_R*Zm0VNxT$bM@NVUGFVj zloVU6DdwxK#X0ln9`fUOr6zx;XM=M3zSIq@wDernsk(WlK_jXG!*Ul+Cl6u=Uj2 zLVaH?C=aO}^E0vzBNzm~>WAd{#q>FElmU>wn$|_kdP(d5|9zd&X+SMWsU!lEx|&OhB|D7 z$TgEfR9oXMPbwaH9FqNuTL4+BHW4pq+t=gqiyz;>3pZ_8#4dKMaz4I2htdonZ1mD8 z$VOD!_Q@1{O9^L@@NkEgG3>?z{{o{(TGA_T+ROsA!$3pgZ3T&2eKl$u=prD0`03(@ z)^W~yV9wJrq{}CP;aA+Uu2?WU&BrhhG*Ym1^9fJg_{eshsz8&*+v&-ox@V=>RMD{k zdKr*T%c>-75o&uUe2Y9q3q~ECtgcO$d zh)8baR8^#78NqG~d^($+k;XR~oidm=I_=|cK$@wdVxr_)KJ`(&_d3RN{MAquNWs|l{c?#A`J=AvmDpzvZTprUsws;PbM-W_4`h#LE<_rbrbm*LTUa- zdt9_Qo0e|=&*y88Y9TsP9CT52^CsaPKAX6^&SjPNAWBmfsZT@cLoOMIjrhuNu-#kh z%F|0vJUj@Y&!psO?Y+3x%clhgORMhB0SOkT(~ZRs`q-n8J;{UsxL2LD*ld!QQ0|Yn zUt5s55CrL=Gy7{&P3ZDb4D<7JTL0~(i?d(Z>z!Os&9i#9Gv|x;qWI=>I!V8aI~QLU zT>r+qZIk0&mqxCo)m+wu{QnRTqWCc9v|IcBVK<%l7~;&|mmT6?9(VbI&?oa=Zk|V5 zb>9U^{^bUKz?AAcf%t}wb8k9x%NEZT0v7!yB_^dHj8NKef<$9!CzgPfw|hwt8aXmR zXK#P$^pPoB?^Olgan|I1lcG!HzEHi*QBatfK6JV-`!BgAgNN~bGLLL+MUWPw27Fx| z1(ZXgh96=G7&cz0_h?_ujY!GU$y0UTFL!S(ADRj#I4a0r6Y6B-CjXZIpgnQ=QAbmq z@q%}%yg>8cMU^~TXVLkAYN7YRpBPWSS+R=a?JC`RsJ3bo)S3)ywoFHFl8BmN{@-6# zUnAL;x8jSHf~5U2{YZLNsC3AODHq!I>DQM!E^_ZN7&M0FDX$9e*Ka23PiKj$7Cv&l zyO%s$V4A3PY&y6KTJ-6k^xZvwJAS?3z#eG!$WlcS(e<8_43AA3gAU7)#!eUoW_-5| zwx##wPp}0=okF;Mf@ja%904=B#yyO8h%OaFbf0h@q zlRD#+Tcxhp1>{j(??nu=4)Y+x0oy>Wx|)sV(wJ|QyK`(`?9UJ9C=_1ss$zLLvolad zbO01(#GMcIgQ_})ZurQ{CtL38MB3{jw4dKMkq2(p31aYsMffke{J?*sTX8T-ZoZC( zXPFe`n96Y6aV8XCTcL8qc;JsTzxft&0-L)H>4c4etWVRJ z&*!2ddkI#AktcXC2oH3M0zi3TFG{Q^LxpSb+6;oRH&@0c2XC*XY76wF7Cvhk3@HmX z57`7IqAT~LYkm^c#wA!QWSs&M-KS0+F6bGkvfFMiynuQqw76y-?a8Dm=>1Q6c0LM3EhO`iM!r4%c&5+9vvIJ>bke;sM0dcDNk znt(NJCt|sv+LAkLEdBw6u(6xe$5ofSh|8vXdu%CQbKtSP@pbPw^7Y>7YnPKr_5E;X z%a{#UIY;IO)8yG>^~|aAj7sByR_5tyot+nHxgk|dv79Xv!Lh66^W#)Fd<{V#+H0v- zyaaBJ`ui8@CPbQ#H*PO)7Unl@-njoQ^<^cA*GGg@p#@OH=z{q=MgF*;z$a?m_0dv1 zWn8rMofo`IKaHSvqo48kdveD97LBdu6n)2*(Tt5%;zA%tRBSGjlghndU$iAm&UX)3tOq$ zN|B7Jq24)3{J|ZruK2Z3`r9LGOOC`(rl!yDTqG_J>+Uv&oyw22mKr(H`vpTy7a}Xi zu&qG98k(zmWn1Q?9xL8-mH*>&^M&z6PC6aM*2G@v`7dQqfbJcmfAh1NMXPW1{yy%P zYadE|C0^?Lhhlbjyu#w%YUq74W$i7Yi8zzhRGRwziwp(LD^UR);2ZhT|0ym3zpuy) z4J!D=d1u+aq2PUeCCV6fBs4Ry&eb_A@v+*so+~JD*#)94My%3cX)&+#DXK*Vp&OE* zMy_#4aH-95>0T0|hTp5-mt9wuGDJYtzZQQm@D=>ABsG7yytYy|$#a>m|?)pHrrRr_k0S$TKh} zQF)xP#7@OB+iDj;;Rk?GIzk*QFfSrUw(+l(en-wilL5r_$4_kpD=t^|^{wUBz&) zC6)-FT#4DRzC5XNBrHjfjAig2DBi@;RmvBl{>y+@rag`G@4NpT&97UOZgE4PN3>;= zQP8d0^1IA7+COSKY)&te$|K=}4Xw0;L}Iw_7>1nIMzNhT%`gdPNF(Lpw44$IG}fD2 zRS6S?XQrK6eS7xEi1ta9(H}&0Wq73Bb16JBa4PJoj}ywErQ?6C-KCI;gZ;KlQuOym zwE`x(nsIK95ek`n+PYeV*9Xqypj<8XIpB=JJ?CV^GW8oW9~Udb3BBtPVFYOy%RDB} z=NMUtg?C|4wAg;J#$jRGt3vlP#`%KuU*&0N3^1%SrKG&PDwtkOg56j+}8S zjo?!p6;L6-4V*?}F)1r2Wv6_S2<$T2f{(aH=DpMq3w8u@Jkru?;o-;2Cz65|Q^Bjz zo@Q^%c%_h1D#>vA(Q9r;07GRAzB0N4!YG~io$n8Xtw+aASIRO>IV23QEuX&!*v5eX zlbH=EoOuyW)>wMbr^P(n1SGYD#WJCYGQW;e;`JW9-CQXS<+91>%oubfWmQ1E%>4yT zl>=!lr$wC{4Gy7tc3#jMupl^k9hM7>!_wiNqAX^&q6VZWeIf%tXVcZ2GD_h|U?V_+ zS3C*I#iRXjl?Rz-|FE$$c*v|OQfYokc#=cLkC)a+99VjNC9b`}`^)s))5-(ME&XG(ZM^soAFub5h0V1UR(4 zd+%>g(=kcV?dG1j;jAIinPX38+Y?>#l(hkAU3t6sh|J@z$GDTwoPe_)WSp^5SGB#C z<*rm0J|%%AK713a9o3a!j%^bIw;-LVWsN^bTi&q$YJTxZD3W^f;&AOp{q??4%u?UK zfA)SF&uju}%3gw{lS-;k{pil`lt9r*ozl~@v?&>;vbNK)*V#cfTEl&`#mxpJN=0j% z9^$PXIuj`(_1<-5AKdGH*3+VUy8ShAtN|!xF8yJyBxxmnPxGzjuO;fSp68fi-+8x3 zBXd7jOg-d|1>Rq1D!Vn52K^hZ@;dk z_T1oY>av+}(e5&ZV21i~D(0)y0~c;H&$Ev z_X>pVoodglixZno;PW3O!6o@>dFj^dSdpN`^2kBpmTP$vnbnQx4wcZhK_&0 ze}9N}F7xwY;bY#+afAL1YlR3V#`QB_?049V#N6eC%Jx$f@H!#uAW!kt6G!4>2B+eT@wTSE8NP_GW}+?h#gFK0z$Xl%d=(BP%8hqa6|1nO|7%V zU%!sPc7(_6X=i+OnoO*{o6M)CND7>}cr<$sJ|5{P?y&8{!0olr>yPonMJaiV`pA#E z5fG8$y3ip&Ii_HagJeX8+LzD<0Z+PDSEPXe!;8+If)YSR4q|)&?K2Of=B=U=sA2HY zmPo&>8}dAAIGCwtgj2j5k@84?B=cZ1m0YI!cN3FR#SJIq} zu{bJUV8g-ut%+Ei&!NHK55kfzM=$6cxlKjO>`9&z4XewisU0o7>*Qv=J22fj{CW`U zvlHCe!;|Mk?!>j_+nU9Py@}4giUR6S;++bFMgXV0(62QH5_pgxu#JEYDDPXsGh`ed zsB?F(0h5X4mWkG+ZRg?1POvYSr3mv(eBm#o5d7}(+_Bt>wtdQ@`+K$;Vfu#h~Id zv!R@TkwggW(Ws4-Pp!PC7k&XqxAn{~o>U0C8y-7|rXmT_2#!ndP|ONbi^E&Jq^Md1 zdf?B$)A+EoNt+0QjjDb6n2MJnrZH0>!qhgwq?G-=(XZ^y^Vh$fbb|j(B|$=SXh)Jet*HPL*yHUz@FgG)zwZ>-a;1|4S@1@ z(E`*QttLKz+`{||osNG2s<5|ova+McMBX>Jc#nxz@p$v;aAC1(3erg8} zo~p27{QP-s3{WMXaK1n~Jq*QSc%Sm}(z!_=rps+bBlPRB%=IEg=gLrh_02KpUj;R` zWq31jF#Q^|l5+iju6F-D7>|oSy#fy0R7#m19ZWvd zSqJo&S_C(~@$-{~H=O;w8L24gbxA$lePZK&GLwZYY2>>5S)YENjFE`848ktf)W!M3 z{zqzD)O4ZZ@$dWQ^Kny#+|E7Yyjerll+3EdI~QZW+jEp9iEc!Q=T%v=D2{R(N)5`E z90pO=?$L&5A8C7s4;ho|6kV~f@vvc4e~{d^zCAARI`PFidC^G-)X2&b;DttE@yPz< z_^KDqfHMU^5%SU&7N>O!+D#EF^7v1?-{r9G^kywI&C<;O5_>U`A;=S-msVKS%7@2C z%4gSLFAn(>K(xrAi*k%+DDYC9A0Jb;R79IFgcl(U3!qtCeV+ob0Nyt%C@1k4>%Er{ zYHl&6e~B{FCjMTqYcIQ<^qOX~)t!;?7*Y+}ShLNRuJ>$I<_Ev|9f?)6AJ(rFPH9Hz z1}R5_0@bf`9WQ2nM5=AZU+rDa(WZP`acuQ6RBs!BlTKpWlMB}-6GY|No^biL+xD>I7p+I1TYI9Umnkg) zT@W7yVFT{M6V}y{;U%LzyiYY0P23nl3dt+LofXy@vD<9urof6#%Y_H{2`pdLRl(hs zEMHKj7Hfe!4KEF~xQ$&AGAth(07@H{?|i`4K;B_bkykE+#0Jv?WqCTnD(kWM(bSRE z7F$sBENMfS|8@(9tI6^U8ACn;U`;748)I5qFlX@mpxY8Esbke)#CHQXR z(iR{}TmVGhDCY^irc`Q6cqTITVVeWj9`}&mb&cVC@uw^@kOJjJBf+dR8d4cbAFq zwLU(XUjOpWGOUo=&{QI0v}z0{o}M_hlf&((Igw&W!*RQv_3iKOUDNc)w$jgH2P3M! z)F?vf6r!%$xOVu;_m0sMYl4Pjb6zKMGhg%IhgQCK(?a!lpt#T19Pirex_>0biR8_$ zZ1s(&Pag_Jzd1WrDUAOd^!;h_BM2dR%>1&@@%lCHZ|}Rj+~UCZm|iaGRkHT;!EFB% z)8|(g-glGSXV+XVQ>H?D)`LxRm-gTjT`Z3vKO>41quIU9!T)IYOP4%dgV}CGrp#Kj z=xk&#hHzmLD;)9A?H>CqDzJ_P?9WDZAoR0Of&a4lUT5F2oG<#`Z*JhS+&?3wYj%De zTV*OKEP6ZicY5XC&{+K1Xm!|>U8})P=w|*-fV@khAcj9y_Wqvu_V46F zDV1gLgOzTd9JZ~7&jj&+J@q;r%Cf3*NLSV5y$$%A{i`DO zGoTT-9uy{+W9(BB0stD|cHh~iNzVa(Y_@E~Enl+47Z_Cp{@T3HL#J(@>}UDD^?gNv z@nxPlld>a^nPG%-13{YLM=3EIg$>)(PjHKw(@M7O+;wA^GrMSO%PPi%%gUbC7qg=3 zYC0h0{i6aeEOt1tTorx~awN~NsN>@?U@4D}G*Pf~ln_5mz}G#(F@LaO3UDKI=}!QD z=7zes(BtuWIStwmZ1&<3Z$~?dz6zY)L~%Wytuhr!v1N+0GHyzxUyvK!&acK%1|*tE z)N$u48cS)4oXkQZLfydKSY5bNGwy%8$l7W{@cBVDma!H4uYP}??Q&~c%l!-C0Dd0N zbD`UjA!L;Pt%)JO=65!RqOh1k+x+0Kr6zKCDME#45A*(?7XW^;5bOXHkuuGPf?0Iq zfBB!`{hdO_;^Fe;u;W>`UhsVyK93#ai+3^MG+Pu875j+Ij@UGFc0TOM!_Wo&YH8lqf1gWs4Z;DD{7dDMtaW$;OBSmv5Gk9L2yj7x=u!a_Y^nnmg- zj5(@jmZ+&%gu>WR9GDGTI)_I}Caeo&gKdCAsLEHU33nKw`4~bdi$XW!z7JNSn3ETF z8KIQ9U!&@r?<@!5cSz*=c|_eUGhqM?WoG!eyx{IbGVZl6@De=41e;G;!>Bb`K0UG) z`)>owu!L&$_v98L9S3OKn1^KfWMvFhxoZZaG8OW>g6q0}a*pb~pFZGG=gvC}WS7W& z9uXnkT^%tV5fw|(*(0k@_X=(rmHDJQi!SK?=*)jWh%R6_t(vFy(@=fsPI|AMOAJms z_q*SHhjTy#Uz097Sq~q-Tt4^9tnaEymg;82#Q9cU@*lA}u-r5V@V#$Gcz$?{y*41j z;MJGj!^o(tGybKwBtmkq^&6+srlh^$-kSC^FNyF?^^q(vLn;BTW4LKm2~Dp0QLDZ#5sk?uT3Km z4Nyz<7=x){CrU>Q@S(I>seSloE`EDw-s}A8>%*p3Wq8BuZ?;KD9Y!mkvi6IFCzfyn(pel*mRgAeWT0OUTr zARh7ex~o%PUR#$Ks?j^SPZe>Mn>{(BBaag_!) z`(CqGM1w1mh)l>yobe#hrvu0FdXqzeKg%Ak`5!T){VC!yiw!8X-?*iu2;RXa5nbfwQvhm0@X>z2d4WRh&J-T<1_70Cx~#rP}%r1HC=(NAe+d#e}{(iw}l zJt6%RYtMs?le9F5Zlxp&vd(m(O}hQBJ@_m;i+>Ver;EH77oVl&SiQ zk@3)UiergL8D~P*!n@Mr>8Y<@>D^8EV>V?nAgobw;LNT8lK58wb@*Rf@|!bia;zH8 zrb82+9TeGIm#4aY*0r~IC63^lAmcE;-es*ZO5};_*ZW%0GJ&PhE!;Kc_dEWDk>vSH z$)=mZ-+c+S=i!lK$yX5_H82I7gt9LYY2~zO?HNwGDxIxfVa}o)>;zDT6Ff(nQSOzc z?;s_aU7!Uu=~RImM$}~C!and|^=`vo2^BbHLhD!|5df{vTy^{LJd9EtR9}Cy6fBv^ z^Fhx_W5d%W7K^go45zH_FeUWq6aV#P2NHb|#upH9D2?=I1lSS(Vta!pFz|?{cPh^# zIuvX!B9tbCSPDAUma?>ozx;0A85mw4Yg*zYai-)rwo_ar7Xmp{^y;#$1 z%X$==YevTO`7k!7rnQc)LCHfUbxoCdNSi%r!w?i>US9j{F|0O^|V>h9zaXp&6SW5oW3p4s+ggMxj$WwK#uaX4y)BfoQEa`=*9{<@JkExU-u|07;#) zg=&I*fewg&x5gds&BhF;j^)s+kA4=G7YA{Y21P_oItYqZh|}4qtqB&b+`L9gm;p zT+hzN2V?=F_4lzQb9O@huZzb2KMF6ClvAbnBvl&OW&Fnvf+u6LDrV1sZF|3F7n^PM z3&~ao)>jv)8uluZPj5O5&bu7E6T5{s7auSIEaa>xt2+0SToyqvd~Efz@hz8Z-4!ze zuY{0wCqJaI`A$SBt2#;2(>~%ox1w~uXis)^X^g5CSQRX4pLr`CQOij{8o^&Z`tz`fGj)vUTy z1@D9Yj+eA)#V=4PSQ`=DBaitUldu)Y9zkofSY*umC|?<3;eUS|uO2I)^Xwh%(4s%z zz`-xg^nb-wx_g$tnhrK19lvf06NmFKUrbwE-;Djb=kw)mW+5Z?QR4Ia{Ul9R6yXqU z^^8P|=i{LY$!`xgm(yun@0^DVU7z%HV#NEh2f_)*HE88EUEodJPRzmGx6Z6^p>Oq= zd9P>l#Z*ZNJlHyO!X}cg-$M4Par|(J@Rr}i$vLr{_6auVEJI#{%R(xjjF`l2$*XF9 zcAKY2o^y{|wQxV(zWp3@CTM7<()o@??33oa@$=^lPZypD%5bB7orQTUa&xO(2U~`o zNB@jGrET_7jHsdow^HYLaDQ@(6}YqW#blq6xGgTUQ0B}t(>&pQN6b+&+5&Hbf-=9F z(Xd<|1&*)qxrbF1lRCdN&_{d~YxLt^YO3QPCLxT#^0|8cnVoVF<}Yo_E@R9y^ZqEF zOI(YL>{I0)UM`5QB1dUhvRQ`G_vUil@@DOtSpHG-F)70d*6D~bl(NG)lngh`5Kmj! zW75H~?#b>l5C)@y^>5Hl@cjLWC5CND*~LD^s#Pa9hN|Szux8YBvQy{=H=3F8e;OV&{efwn^_-{d(HzsitI zf7QLcMsJ;E@m||J6@!Uos--{?ZZsLwE1Cvup1N%X~@}AThD@J=3h$)weSbXwfD*1=Mv&uL#0Pu$-DM55s%`k z&WmjJok3(=$i;>0>*Mw1p|_@u>L}Bzd%)`O-QU#*7xYkez}a$za`e%J!(y||48ccJ zy{ntszu9=%AEZplrTP9d(eE3>f8BJMo6Alv*()aUOvoinZ_jsV8-ki{9rjBMANb**~PkWrY#km~9 zt@~U$e^_aQ5eZg=FrpfhB&#Yy)PSt-VM)BqTsz@6m$`RQTz@2gSrPtnnR+Q9D&_=7 z^R}esyqY5GR075dm?@Y6W7F}&&4BN*rh)zCu&9FAfY-0=F+!v1vIphG`wcv?R>E7Yz!FhWoR9!Y8BFhxGM_<$Cf+&unwVe)%WsJ2)I z-{R}j$YF0a6cMRFp(AR=hY?wB&_BCidJ`sA*277a?`)~ss)7T0$}jPYd9uG#u;7ik z`Rniu^+c=@l^J8m(Ovk zVRC^YqRz3KpO)&;sA^0!)+%9iZ%AAV8F2@WCM7pc9`}Th5|gw5ld#FFv%PP1nw?^` zU&`2?T9~3sVUACgZ>7r1r+-9GlcA70qb;YSxwiNhz3syBkkFP`2|UNCrE=5dXXQt< zlI@ZQbSs#`*Z0rJazjj%XOH!xwY<5*h*8#?F6| zFoWf??cV5JC@fxkQDb^=coG54lL~LOLaYi05XOKE!lxi{XzeAleN7$bD|kt6(^N}J z?6cS{>i7}9h;eiq+Y~H9Zx|Or%p0KB&ERR2z>wBvK1Eph0L`-Jsg2$jMarSO+sJ4; z!pO*ZATodmY1bNhMV)b0MtbSrkSEv)pkxoKG{y!>jCbHtxu_D55*EuP9gb^A5DUbP zh(?}ZmEcoeD>*$1@1R|Sd)c(s$U0)zlVn@^_=CktA0iNMZ1inE3RaI@*1ce8p0eeN zc!|AA_@go*t>wYJ3{=YD!9v)M+T9bXTWeJVC>80T6JOtqNy)k}5~6qq!eD+=a(ucx zFE##|MljnLsDc)n}rGm(lNKc;4-0Z3lpD z6UDGBpkr3#UHo{TTVj~PZDI83aJyKPGAaU{jL+&4mul3x=GROZtyZ0@2*l%-i`#o~ z>7j2uAEzzdl|hE>fRBCMTN0gcw>+@ep`yT|Fg|VM^6dLzEiO0vd);yD7dk;o@}k|0 z&ik83{H&ej3|L0OMspuc=VN+3u9oJ@C7OQal-TL~5pIw2y0U7sdRDvZgxelYf9R~r z0vPhS9aHKW<9~O&-@Rybzp&aV{_;k);ET=fR89;}cymlc78!SNA^4#J<4k93fi0JR zfHaA)z9M3DQwW&Ts2^y#B@ttOBS<;Mou1Tm*Q3JP2V3y-FE_iw=ZT2t`Xqi+K^t%q zA81E2v-fo}qfnJWKFwqpT6lc1FJz(mE6 zmGvR-bLociDaMqo7{)1Q#(VCyp$9fvgco)f00+AzRbF1s(a13=N1|MlpAgxyr=UWa z18c$SKFqcJ_Nw_kTX=5$&?pGp>~ds#hs7id8HB$dUbxhhSC92qCoUQ$Cp zbD-R|ss0@#C3hMw&4E7Fr4tg`dPe&plZEcd58t25x$x;J-p&P*SraBgvidlNB^)*l zTUpiJ=V=a4X4*3q=mh!IDM&5si%@z6PrMm$6E(;A<4T}AfGyiE!eSek<(=6x@13sZ zqpT_yD)hzCLpnxMjmTzKyqi~xn%nxmOIi1oR!!S-i-0?QD35c)DCg5kZ>Z7M>T9E) zetMKfz<$El9A<kN}L2`DV1Z%M;6Y3Ufk%#skdcZd$9 zuNR#vnRy}IuzGq#K8DiwBeA~ElAe$2;?nLP3q77j79SULA`^QxAW9PoLE@8xc|M;= zZ4*(%1sCVikqr$pZ2XaJAf*EDS4M~xkMJz}4e7hG`+RF`kFy=%o0&`{3xx}4KU`AA! z0>ejMVq)cl^fehRAb*=~nEkfv(Js#2KIxR9;`Y(a7y(U;86S67f)s6nrnx=9s_09u zg`(LjNt3)!JThXrKfj@PvZZxN8R+H1OAz4BDFQ+41RWjAFnomZ)Hpwpqan6Tf?Jp( zz$ej3)m(Z3s50z^KEl!Qfj_VxYCs$f+Xj)Kf5fBA`EH=Mz_(y?U)ji^3CxElZF0D8 zXkUqFY@2_4OYf~Vy3y=`H`Nqfn6xJ`pFK$6L*PZRdWo-NaM9WNU0vzDu#}SdM}psh@PxmgbEJ2J z+sv|%h!5`8?Kw^-x?59SD|dZT83EPem=#y_){2Um%!X*w^dOm$T4PS@n7Cy-O2B&_ z`!Y?-c-Dfd`nQ3){GB~{<-Y<=nch}rZLl#Xq<4kkL3M2vhoMDG;Hea;M=(-WHXT^E zk?T6t^Y&dzr#p6%SGp|(ka&W8O8uK+N^O+kg8-os1W)I4q0XB(Ezv$^Whwk8zi|(4 zG1Yjtmvup#%;jAA|021A=oUpvKfEp)kV1t58A}Lc|Da7e3flL*ekJT}9zTBTf@Q{` z75hix%H!=%5f-!YLf8xeR-XudleDv5s5|B?H2 zq*e0qp{1kAAh7D90bo~>@Op<77C!3iqfK?~6>!%#p})x9cR8f1>uHg7-CISjw70Qw z6Lhh=?0x?(8l}>AVbULaapU=?`7Yf{HqZz%f4{3c?H+Vri}Jm`+AReQbA;La-$uTN zXRqX`6(0X_d)GNb$bPu$Tz!xcP~gIUq<5vyL1(IIVbA{ALH6s~#^Y~1%Ul&M<^G1_ zti69hZx9;C3QM?WrRF(pHR`{EGqqdjBNx-_MTt>Ok3E~zkO9jB?I z%#~tkU+nSNL9n*l&wjiFv!@CM={pj}jk6!;u{hL6KSbI;#?y1c&*IwnJp_D#tj3`- ztRp@04LhP;A4!}MTz(^^QdU@&_J<793k^Q2gl#?(p%(bcFl*%;He*>%@H7vK$-zU@ zr|~3cFH4W|yK-}fGo1B0Een9?y*&#SS)XlXwPU@;jgBb|tN69!=C#ZHE+kNgQTIgJ zjr{5NLt9%ElXxR3`~li&1#o|XLk37Bn^klDM)CZOx7m-7EN?|iG=q%WJ=Dtt8IExm z?;yvv89C6uI0OEfSh z)LsrxYZe7$l2ZpZ=a2Uo*yTj9%7FrXp_7uQZ!?f|kd}s)3l`JS$fjW(9Nr+&o3y*k zU(_RL?fSH7#$fN>!6xzzyu+NuEWEasUWB?qw28C_RAob&-~|TfswGnm*u5X@i!;(o$e9mo#(lu<&K zAR$gQEn*hL9ZEo;{dQ_J_#?K+gQcQ8=6L|GI1^1O7JfJifgZ7sLJ-2hhBCadZP2b5 zYBMkyE(^MAUga57wz7*p5jj_uP>)50-T4l)BsB<(%3;Tprjn9QHE4p!zruV>S_LRt z0p==82C@A5>hf7(t<_EA@icN0yJlvT=r8Ypgzrn?`&r?ti7ocyswL!9M|{7)>1 z8N*(=F3bM9fOB)k#57L9h1OL30c6jvH&h<~JH~VIAs^&MRUedld417(n=UC*u1_i- z#cin+NB`!cvGP})%DKA_nXXOleRh*jT#Z%3{`H;1*Cub>tZg-M?_X7Nnp!XNt(1t_ zqMXxXL%S;pv6USSr2(7T$%sqni(qU<2qP9AtP>kXeT4*ZLxmxZ2J%)0nij&n+PQ|L za+>N$If;L&;tS2Il=f486)7a1gL{28l3KB>f<5|@Ij+tJ?j?gI#-0=9<;M4?E`Va7 zVH04aq32JZ)r$a4+CN2+j|FPw+;3W53B+;hTB!90t7q)XONeI~-=rQq_mBf5v&v5A ziVV2%f0(aIj=?o59Vr@>_RA)y*!5>GTGfq(!O%6{?D*yEzIfH+ADBJF_>lB(gV%GlGli13yh}5(9^W|M!oJTF7PI z3($F|)SubrxhsSXSCDVRG2kUBQL5;rY&-)YFyT6v=XB0!C?<$~IGo=;(A6M@j9ZA%!4|mLoZQFJ_HYS+ZwrywP zOzdQ0+qN+i+xBE)eLe5{-F1KK?my1zRaL7_byu&wpY!Z}p1m;37x{nZ3G!eLfpy)n zNo1yiY<8)|FQx52M);D8;eV#u0wsWz_~*sPieuH!s=@7a8`EhU_OEP=ceD617mXD9 zlZWG`@exbLm9K-kg8j4-a)4d4fL}DM&7;!1e(U&x!;fU2Vq6u z#uMTCe{dDjzq8GJ7k)(|6GRUH$LAc+%Nz@?9LUj#Mgd?GnB9{YTPoJA6bNaHfch+^ zlCbO$%w_(d9qCDjHepl9;rG3J`aR>qAMajk*LpfJW9j@n5gjk|a_%s6*!8Mn;?h`s zcES-SaOmhoKSl3dh2bC39R%;h7W^#*CM}oo=_eVPYUribCexWry_*d1!g-k@gcs#? zqv~P6)O$!M&~N-8#6!YrdXFd25;9Qvm=#L(K@ki%@w=$vPX@&z;u_U~7X>Z7is0?&(}^Q?H2eNbD1dgQz1< z|ygZodn%TAzX{J)G(-S(yUKP{h5XyP5Eu!I6~M^m_}R1`mmddY;gHXU6Oz zo-C2j!n4#8te~(}Ypcmg(xB3DIN8^@#606rFt{HAmzBT@^~+AogEPc0I3qNdqAoLb zE`8vTiD+%v!j}OLL|@_b*kN9Aokzziv5fe_@L^md7=I5!Wm|-P4RZcQMh#dPNCU&R zU}qpE92E8pO`0VtI7icjS4)!$#Hq3?*qYlC4&BZeNFkpx2V2B4ED(J+jB7FBa0Ah* zUfBb41WPB@Ah##jzZU7a(ARKJIEHA~SX@F1kF+GgL*0GCjynXE@2D)>osh7kn6nTK z@mln=&Q`kHjj0WO%n|_3L1)UiY(tbovPh4CJ<=y1?&R`6wE$#;ijXSMH)R)k5@E~h zS9XlN)bbQY0;nioudl4aova;KQZ1Vw3EdR~2ZFk!K)R+&U}Jt0B_v~alxUQWW{&(w z4TnJZi5wB^3Nmubi%77L=b76l#jls{cv&)2cZ2{+oC+;mQ<8FR2F?jZ-r&QzOX5qf zb#I`!WX(oJJaOFQrJTzx``tdF(iXzbv-~4+eh%|UNz}rO32QYLbRbVQy^$ew;XNx_ zlJeJfzh5J##jRMSc^ipeX+yVU(KOc;(7aj8JPg?nxJ0J=05Q0dkemQnpd!kdo?2sN zZN^Av(ePOp%7XLNEX370iRpAnB|12mf7h2|Ia4?QkkeCMzED{K$>l7nur>bSL4Rdy zyVD8m_Rm(^Dv^Qr&F$x7?%^9HZ*apSL9|mlUrps#tv%85d&|uve6{Jlb}o~GxbMlK z3>ZY;yn`N9z=xKi(-A~zcH*~OYj_2IZn%m5=3$3G4T_4IaF%bcth8TDF26JcBvzDz zn&07HhH8gAHaec7$d5{j^G4)Xv}5AcLoA>hDw3#M`S^6QcX|Z)9y(`Q7;sIRJKR2; zk8b`dEFP|TLeM-P>RmgvQ`VQzI zG33oYKnQYYj~(gQCO50qejDOO4)9S4^8JU%xo!f-?Ox~ZfEzJ@5cm#1m@oa7#B6SL z{4_Jf)9JrUJV2K~{9n6fI*AT2HQcF8EzRk@R^zPKfERSXHT}!|Gp{A|-lpFF{+x?A z>Q`8G_qp(%@BMqX47K<1Fty{1$D(EO&@;29Roi(cw^IB=0H@nDDlEJ)L;~DGG(}`G zaGbY)I*XfH0u={DKaC8@Lh^q}a`bG7qRxBi_UZN^a6I~GNBugdb)1d-F!_p-e>Z$E zFf5pHAtH!!kV-duY8Wz|CFkiw^mXmi0LCq1L^3)rlX=h+ zUQfrBbQXMrh}-h?^uDRz?z$@uH4jX)e#MKYPTP9j*wWdhg;CI=@nN>p;zQV?MW|#c zuLt@ZOK8@5At3VL5D7?YP{tGs`PLPuf;UpnAE;`u%W1wCFH}fwS05FJvS}_g=n&{p z9`8JWKO>}&Un7R<|22nJMQI3<<+39`G@G=qoY)hLY4h-HwAD>4o)1s0-9#@$sLnLgckG@vXb~)1_VZQ+bE_50x6!a3C@yeCQ&I3$6#B;5F#5HLgnBP84`1y0d)U!hjt=01-|9d;zW--op+(9Z{E_Ln^;fAMV?-a&%ob5US54 zD4B=`(qET^$%ey$_-9uOlrUjPFbpp^Yo5%tU+2KmSRMO$HQFLTU2Fyz6Yk}zSu{sK z`9s9#7waD@h$;ctm?rHY_@H%K;8wpej2*eTARGJwc;|u3ZX&_(AQ^o)odXCKw z4TMHduLlF4*Z*!eVQxq~vAH@kj2x~k^ceQSUW~EseQ4q<%NW)ix3oZ1lN#|kf4aN5 z4P?H!m|?^}p1qs&(wK`SKaqU$`fwu$huYG5`|e?h4?@*!&UZ_8&^N?@Cx>4ehr~D_ zdwMxU3JgHnIR<n=5tWf=~zGMB^)$yxhY=4&I zq+X=_vlLa=qd7N4RZBgc&zakPonAQ2t!~Htb!r`-fYkO@S)U&$6UUECn{B@qqT^@d ziQm6{v%_IQ!64DI$(=$hDS=Kv6EQM}UOa)AaycGhvQ++fE3*MFn;Y`KpI;y3n zFqfLpN|Mvcp=l_Lrx9ddLvffUcbePsCXGb4rQcPw!%)fkH@RhJQXMs6R@%W_YZYa) z@*_{9o*@A708^#NaSw(%5%b;7&G#E&t8Z7$pn9*Xx9AaBaY?oI@tMW(l(d19KZ@(N zua{+7ypJ%`p=08qk+X`K)JoY3Sz@&$scyAcxocc4=*DCPKSabcI|ndRj&Me`Oy*V; z23%_yB^$X)p(Quz3i0RD;oA`Jtam>0tz<1=V$uszjk1kaRjJsHV&!N^^C()74n|Eh z?Ijp&IO$Nb$%e%{#%i3^KLvP2L{O`1cL)nWt7nsP zq)~1jo>$$~rs}iuk@ImNOvrHR~)~!S%rJzNA zS@ja&IdgPQ-YLSyVgvKJ7b2kSIz9|cGjIfjkdgY>IT;A$j26N16c}Wbn$J2I4?pxBIucTz_+3nsNdT4 z@Y|&m*@4aUMb&JukilhIOq`NrKbU@PtUa_9vGzL$qXzXkF1Cdvjxg2ON)Qo^O|F@A z?Ms-J12a0;hTV}GZIi#pTrkupBxp?(Wm2l~A8lwZut;_mx$m}ZtW_(dxM;v|XExai zv9hWOKt`<=KW_0qU7S)}ajW*?)1grX635Hr>(`wV!s24xd0U=b{^UeZ$r_jc9!bhD zwkCvKrmYOyq3Ca(3J|l(oMS{vG?v?oUP?=%vcWFk?Yu?gZRt;8C&O`GPOib>H2kH; zPQ1HHo1?_?bXG<F;Je1O0!wt{IqW+H8&B*um&!91vjIN}L zX&P;3(YVxdxT!*MGPs)9@^mSzAx~MTG1GYK0+y5}=7gHLhMK%0&AclIjLAU6s7N6n zG6gnItZ4tF*>PsO4C;v`U(({K%-N<89Ha@j8r%Z0tO{pcBz?&`c26e*^|qw=^^;?m z_0~}aXz1LLUWlF2TsIVh zQAofiXJGtBm)k3|;N+enh>`hF0=#jAA5U??2KM@a=AG?&IHUi((1KzAFW&#(@#YHH z^CSfg-9zO`tugoIK|;u7i}P>22~Fa9_ut+T=-qWRhff)Y zrysMe_v6I(4GM$SUVjXEgt}s(98I9 z;Mc~*6}l2=De6a~@Y5E{{`sHYe}63;MxjkZ-20z?SH zgD--j0iu+34*2peimI>?FE`W2YcIbzX%ad|bYc*{9y4JlQ{U+kGPih2L5x@(m>bdo zB{O0$D&Q96Y~hSaxNz7qniq(O>fACoTYjX`&$x+cTNpb-12VO#AS8c`!=VHREz(dG zBGO>a419xX<#+Q}d9Z*hz>f5S#wNN5-McL>+J`z;AKVNPW7TA;z1FN}-;MDaH)9VY zCnew80W-Q_BHm%X_C?!nXdTi=-Ieia9VyZj$}a5j34AdOGPAphb9@dS%yN+MJ(!JU zC1OvN8-9lv5Zn}LY~HNQH4$|T-*koN_@b!9cJ@xGr~$+u(aax^rQ@gpK0sLtXm^t0 z?Z6JbgOlE9!;YGrY%(U1G2&^?%+2(T)GcJKXvs^vMa;Jz*Ci|4r_}9`dJzA##ZtqJ z*|d|~#L*X~b^3`(0V#djr?_-R3BxI>A=Nex$wu_ZRFJ5g4CP*9+Yc%ZwFPrGbaE_? zpn}Tob7v-L2VbKsGDFy=_5BJix{`yNz`nL*I5TJr8B5TCV^oRh3zm+zkP^tcmIV4s zfPp8NB#_s^MnbXx&uuTHta)Xu)AqW^(ZCiA^&r#xOkjHTK=gY0jCe~o?d3CMVm>cK zxo|s&yRzMmBv=g{z{v5CBn3DDuEuAX^CHGoO;U(PK!8H9f-olI(0MMPO;`6DJPxBD zRUCE-(FqY%5*0Q@H9z{~N7bwi7^EdqoT0U252P0i>S-gHOJ1)}m>@$xtdNajRlQ3f zDsP^aFV#0GD42&~?GGy2&{eqf@o^rk#Rt(QJ|~q$(`<%H>$nT4MpfuM>94fW5U7zP zBvf??i!dIohzy4h#ZZZ2)>xR>m^x>=*578r=&TiyXc2fz#f{~~p`oKKIXk_TL%Sn3 z$5}D%5f|buEcVgn_`QC5NH6mJ;QHRI{*wX`7VcHZzz2rRSZ+1D5=#>C44Er3Mp|Gf zZKNQ7VQGEyPn&i8V`+Q!_u<0@1}O@LJ%sZBR}_Od9Tt3CPp>YV=R}7IHj)hD(r2e? zTEBklVWWmdcK_Y18ryEyq)}`s8Yx9V*6-P~+i!8tIx~mYvBi&60rcqQp2Th(*5^%P z1aG(Ny^lS^x9iMW_>47Jq+ECKzcHF@3aJFVYjy{1z7QImI{H#hoEAqu>kn9$SdQ{C zwZ?FwWN@bmiu)Zc7U^&F)(iNad#54SF5GV2AD&g8*9%pMGgYC*2OqD{^fwQg7>}nm zzIZRz;|+jvHcY9krDdj)fU&AaA1I(?!l~`CPOCff=P=5|xq&pGLp!_cWoM=|z=&7a z7eRTloZl|%c{IcH)Yl1994X5NpA6-ms*u6C9nbDFt8o0vJ!ZO+*G*19?{7w)V z8uq0K|46dvX5q2Ly|$NSwdajnVxt#YC(A~=cg?&I8k~c0VY1M``fQ%tkSYs@E7yUw zrSjE7=w5Eo^ZfCVN$9aaIawpG1!AfuQ{F>Z_uIUKPBy`NWs6o9)X%Nz-|}gdX0GZo zGl4)zPKnBIqT|?cG1Ta_72TcXuwQR3L=%3}6x|@1X?fj}X4_wU87?xO7KOU`V5m4cb)=&Fh}Lj+BbV#=cleST=Q|Dxw9B4wYjbpG>wx$xiO# zXgpK*^xpb)YvpUNpb;+i%{n=#j0+$4vQYIvvGGD}VjigWqhzrC*cqM+1!fr`4CpDo z-saIeT$}?=YZeF_AqAJ`FSs}F0hgC+0NJw(ZhmdV@VSHRbS*OQ=vOz;>L=I7{AnGV z9^_LQxVQi&W90TF3N?O9d)L$=bk7(r4D1k+g=A*_1z6H-LJ?T?9)uQ@9IwYajiDUo zhKq&X6bqCmIoc}!0hfV+r4z{hw@K2cZOF7%)XNG!G%z{na2G9U00ln(3NgL|oVq;} z5?O<%?_StPEF5)kI2Jl8aN!m8x# zNw%3XLl%u{MI|BCSar6J!>|N6_5$GiFywmtqe8bKKXo(446UF(EKeOEc}1V*a**VHyp@<)GKZ!G)hdoP@V)WQ|Q0Q_qq#b~iVt>H)B; z#$^{kqXt<+HmXJjvfyv+!cR{*sL+NrjW?!9M^ z9-PfC@qPR8VlO{)e{AsWAbmVjTp2tO<~v}7R@7ZiUF*se!gPJ+_GcAyD|2uJj$7k7UV3f2}5_2H;Fs|Jg8YxjPP(+JhFQdI3#(?cs{f{LO;12-r6ZXAa)PQCM5&Hiz4Z(k)o(b@| zI=|)PM7_7pM6HWE+Nk1{FPFT?%sU`B9rJEX66zBcFyyvb9tTGt80d8 z>+XCF{oNQ^b3_FFM(NY=k7=tu#ElT3_pV6@#5j3s+zA4NYEd2@b@NQV(ZJ#kftLkG z0#D8j(VYwkGG1_(8p$?NmtD}a5G~%lOU_-Fj#a{I5RCC7H}@awS6gzY-Tto6o|CoX z4k40(+g!MOlqffP{=IL9vV|joPORQ%L;1^a-#{7o?!Dd-7tnntZjo2)pIiLddb--y zL_0BF0+>Ip3b44keSIZ=o5-myRmgu^0sVBJt04O8Po=@p{u2}^2k{^Q5WWKm>my#T z>hF#;`JXjn8#oYn5cRqRoR1&j19}kpY6A|*|MO1%-)QOC${GoT>B;3`rt|#0>oWgg zYBq3p4FQOy>TKMcWPTr=3F|dCZ@5({oc+a%W4P9I|CX}o`{_~bak>^MlZO?-Ihh3G zkvjTmYV)|})8ft?AU))_#Xtw(IcB!M)_d7qnHF;LcD@NHSs(<<4~dBXHvHgDGt@s- zW>~T!aZTkoYp_Om8g@yiG$Ir~vK6%xgF7V;pRaEkOZ_TWpUjnm0>D8x15}v{vE1Fw zP9tsko>Nw5&BR+AjIN`V=+LyZew8O!@!`5GF3ALwI~f)OaNwITQhFNp@)vq^-gAResI$e$>FC7qTF7mm>j$Qbq{i5Hi9b12p3=p5s$veTr`~2 z>~+7v3AJ)r+!!r6C!y`HKE%0urB!F<^eNg9pkpJNz4kp)e7Q#^1^YqzGPtyaJ^L8! z1*BJda3NABwxBZ2Q75J3atqK5j0bEq65GJoHjRiBhf4mj1wX(4PZ>J00e83ZjX8-D))>~{gzU!>feZI?TKfHBe;{-Q%# zB<%3BKZrQ-Mx}B$ur%hXj+j8vKt)4b*m9491+G9paZoZtGhrP`+k?g;4RDuyF8N)Y z)9sz0C}}HafwxSOgm&-8&M4-JPah6TSVm2=C2lw(JmLbhsaSTNs4VhrUpl!aroDVU0L68d}sdRJ%|5 zIRmzb%dI=q9fH-I3_yK*z&QZFC^8Mx{%E?kN~IU7b3q)OT_qD8J{q9JqjWN>eI>es^a67vh42-d%M}zI>U|6 z(Go2vOYk7=ivXk?JQ{e&c@wM|SrqZCK< zwoM)JXwW#@JF_|`yj4=JpS|%Z?92Lb2@0JChS>VvqL5Krlo<2Q9Isj2_Ws8PR#>CL z?>AS}0k{U9ntqvcNi*+)k-{+0Jp&*D%Ll)2+o$0jMt@^e$^S-mg>j!f()u44wlgWi zHDI(~-wW?qM|V>%rTSLM{df}*q165EntKlL$LfpU2Jv6QFgGs$No;p>{g>jpS)AG) zMQ=r9jzjZ5GZ5~V(zh2`8;JBVDx?>2f^#8Pwl}1B2kDXhZLNIK_`RTHk_d5#MRFzF zSxz~5j#nq1uQpf&0OeNtSMs`BQN4fQ#+WgV#B^)YR2$ld-V=};!UtEIXe+@60oVF@ z0C*xLENBVEZUX1&r@E^GXTwE)0&AmUh!dz(M%~k}NoaMD6NK^teFgE~m%@ZqA@0aG z(k0&>d+YB^^R@>_zzIRfz<2A>bTB?(2khhBp%=N%hoP=@jSg9gOd}R(Lyk-4Z|C(t}P9c=XU8nDxDQrq0@q7lGva zUuNeJZq!JOD=wN$6NWsO9eZRk&D2^!2i=yI;&>GfFXTe}oeP4Z-+lg#vTV!!$DCsf@^tLlUjH`eG#bf3Bp=pLw3I4VwtB%2cSx z(Dd7s$C**iZf*vJn>UzVpQ=zR1vNpPD30YT=k9 z8t87Tup0i+oa)?Al@T~KW7a48N9_+!f||$*`wFWZihE=5MiChk!I;anWxG(8IL@X8 z@y=@^@a6#VdP-%Z=rh>1b0PD z>i}e6xp|w`Y8rzejqv&Xp3d|+%t(&Gkgs;zDaS;av`Pwmu%n|q1J4qgN1Wi58@lh2 zX=ps5LEpy{v6~3@}p-Lm}y86y<1#O#qqd zb1WMT*B(8m9-(Vd#DtHAn<3XyMr16KQxj8mheViEjp0>1$48n&aZ)aV4PE_36lvHK zd`N$YbIV-U%PQu*6+aXKJyZ({U9v_e=4yKw`P0kLW<*-j^Rg~b_5{jZv5(AeSQAYC z3oWfPg{xh-Bve{(P9-~RpjUO|9d9sZiY8g|Ss+&oOH zWrd0+M*d5?R=>Q6B1u?8sQ-_o43Pn#p=L}SSI7`4Grp#jqdj6QE*7~H4y8scUkGMu zp=KNa3=KXs2ToTVs9vA|b4f-+pYSD>P5R3Xz$?6l%sCB3NpXiRA{c!{#E4d`TS|ev z&&M(i1=)J#N8d$c`gDV6k!~5&%`q{%z@c|hDZjFaS`^c{je zQ9~(5Q5pheVy-bNzk7qxISf*5pe}G}fx5qFZl=M|^67+TqPC+fbZcj%_c8dXn=%7f56z;LZKpFbUWg2^*}`cPX%MJy zd%n!)96n7TxHts?Al-??H;|btSlEq$Kr~pjhC6uxCpApL#+H6LeH0n9Qs&{_otjjA zP0~ma0bN=nAEoHG@Z8C5+K>*&WvXLiCb0p&03F=EnZa};adB~$1ke`k3VnvC;c=Z= zkLO+c)MuJ`W9~viu<=3E1hkHMb(F-g!)%7*sW^Tlq58*>6b+^>>D^&N)!17yX%91P z=yLekepdd|UQK{`Fg*mQCriL(@Kd?CFjF$r#MlHcI%?=xCmZ*DdX|LxSAJR5RlA3g z#_toqGw$@GkmXDG1GKU~yQ0?c)i{|Hk^SHMbCf^`z_3J)-RL${8RL=5n zR2Q2pv!12EHg0>m`llAP!mNLO5RgK%UWXdLrGbdM0E9;0F0C8_le?mg)|Jcj@_j27x&&^XR+S?# zHAMSTJ*PzeCxXZ~dsUKbBb#P$%^qEE9e|x$@TX`HYw3Gw`58OwfB5r1MF;=ZvHMOS zQu6!+ip2sJ;`1beXlGWaHoq&l9zq(}4sqIkTG$*Jk&A(22VY=kuV<&rxvc2+-f`t3 zA*H$9X&%AuWO)TN2XtX@Es}BV+hFmNm zQ$95c_@{Pi1vWeOVmlgNUg7@Y=bPvA=y3Bta;us2Q{0FY;oh5Rwz0~~+SKZ~>WyDM zAKMq`oSCMQ5Z*#rBKy^)FZ^iy#*QisTmwT}S|8ab=$W|(0884~IDM}d#oqRn^!@*Q z-g5tYFi@Src3JPn=$#b^0Ifqj<=uw%_icZ;iRc4r-810 zYPLX~{Vy%>|BRi{{cxcA=$ul)_J^W;;7oTec1VX?mafj7pol#u{-W#PDX%mz9U7y}FEw0nAI4_PdiEUeE8#oypPpdgx|*=|;-u z!-R+pMGMV^iCp7ulay6|Nd6{mGKR(l4qXusAK+-M(mQ*NOB}|IWoCR{ZTeF9(-t4Zv2-~H#+erlmDf$Go9_t(3lUm;;& z;#>TwKOKeSZ8`kxoevK$q9$Zm$!HN0P=;#bldCv;&k?O4=ho=dVsCGD9sH;TTKcm| zF{t-qz;Nm`o(2u)jZcCqo>&tZ!!uuGh(P5sDcU7G1Flk zH(7dpV$!yRFO`ZAhl(t92FFEWp9yZ}QON}2RHEtJR(y=GjS@F?;@e_NIh*99OJfzH z@n3P;owkIYCE3ypp=pQOP;7{@Rl2bG&yVIe7!i=djyj-ZEe^uQ;ebNgXPS(^8?uf1 zF|S4;Ek)f?+vB98k>J6TfE@bIZjVME)(@SGmc4)GR!+f8Fc3+%G2 zG4_j_o#HpyM6h;{x%Q;hRvO7DNKQV9J19=hV-U z^G^izGsofIz?EAQqU!a)R&nJqDZsg*lA*>ykfx^O))Y#qTXK_)l#4MCsXclK zD?y3Ol1};#HVWwF1;c=Z$8Jd&T>-{QJ_@R8Q`T>TO$EOkG&xX*IhGBC%PjOF8hrkN z3U15}!wa1fr~)0cn;p_FL|n2GEWRT}4uFitJ@vFo{ZgNiv|WMH)Za#dLAkrLKz@r; zLsOt9?yDK{ueAi{QVT=p^-DbKk#77uU#-torG2;V;w4k-<%(S^`f8ASsPW_&{0~gB zpP|UohO}sVl%$~~G_V1EU_lsUD54}JD#;|GEGRMHik7H1A%-3MOdg$^i;H^dk4t{p zK18q0L@qO|Pb|wq#|!t>vM~GB__cYiS3(xoZcCXy)s4q%9`X110S3n-Ewp%s7{8-v ze))PkBB%j6zLQM8*7gPjt#IB%s6M^pZg5NvQ1Rk68O3w4wXAbuv5&ZlI>xbP02*a~ z-M6R98?K0>=GrUI#0AUl4z%kf*iQXrAqmh*}B)RQc`^(pv)mdjkpH6|^S zTK^Uvu|}uN0V3S+AyrY^R&@5_iy3;i$$6_pG^3X7u*1_L1EG|aD$st_hPM3lOVsv( zNHdu^)!c79KF0{#)jjtYg6^v4hi>x9n&4;>C^%@&zq%Y|9>XeLr+TO#zGsVTV0PzS zP~UE?c%c|zR;uIC(86^ZDYBP=6+wsfXZ#3?DF$eegpEJkzQQCGV&@KJF%$0o8l1j6 zy1oo?$hO}OIGzH^hdq+@I47MZm%g^1<3El)YZqlEU_gz1wU@5zWRkn--*A9J3F6AR z6n;Bm{tPk>P|0wFB-cVWA{FHfn#yMdH~pDBv1i#6r1eFKQ)A0X9j!A*1D@nem(F9A zVeg0dpuancv!f5vG@IyhR7j_48SeEoA}wCadT4YK)_M5UB4vhB*I_o z?`_k;J=&*dJQ@%jdLL z_xmH)>m}s0#fx|}Ctg?bHhCB*0P3d{Qk=m{1lDWoXJe9-!+Y5Dp94gV>sCZ!TMid5 z^G>dsM#m@XEZ+tO{%K;ichh^mmCfX;x( z&%+%2CwvED@-vrN$ULYUgj&BBmjLv>-nXT!yiXtE>qsfd|C-PbV&8{2;rnizE~gDJ z8bcN2@Ai;M#?svcDho7^v79CJzohpQuFS=}PihdXnY35TI+v4$eHYTxOpqbIz~wM4 zH!?v@72M-lDJC_-Cc&G-YvQR0y;g?u0_Gr1#;vkdz*$J#@{Ky%mGXAkwA5sQvdXp* z^(H7u;T7g*hBXt$v|u9=`pb%@X2?Y!Dm)WtHZX(D;{U#E;wN^(aHXjtZNzia?4Eaw z)|uW@Fk8C|ozr8yK%Dn9BbuHz8B%(X02e>ujKngW;W7)! zrSj-@CE>u=uk%8rJ|d$J8kHlu9I1pfPb08PcSV;+P4usXzM~Hn;>c z{hJgJ7^haP-B0IPhe^!1Q@`fSe}{*%k`)zT$wTgE6IqEZUPKb1G+`nh-VedfK`zv>GF1en$EsipKd#H^5) zc0)<4VWf6ZpBGe=nfrKpzuauGaq9g5ml=1_%FH9~e+H+3D$49zbU{6qQ3VPJ7d-a9 z)R`Bdtd}&K_H$64cUrP=DwvnRWvZz*h2TrgKO5H?9{-pci?X`x3>mbFOYCeAs?j0s zg!siy?hWHErlHi>g>NKwp+lz1)kttYvIxn*Ov; z`jHM3%NV}6;&=r3-8r%pU#l0sP zKFT||3=xQ`@x@nA>O@1DG&sV36E9q`nU>U+pW`|gIDnz28%#}Ep))$C5bd~SDmSAh z+V~Jyk3pn@QAaj#y_g{L1-4%$v?3EKj9IP$wy0$Mw5T88mfX?Y-VoXvxEiXg9>c`y z82~*>~G(m)-hHPoh3R`DD~+1CZCLunAHSOh6ZqjWM6w>Jbp?}`kxg0?d*uWxqSz=X)s#QBtLHg$nR1kcL<(dV#SmVfx9-q* zxHRwZdfG{0bmDJ!dK5Xsr&1P=8p)4dvFj?~K-FkK%!NWf1Gkb!_fs-r80oEjpgvwuYo|r5*oBesmygn;}$X<#n{z7Kz%33WDU~S$&rG z;S3Nn>0zR$Dt2@Fj9s<3V*2xDmvU(NRZ~S&rNGD=0ui1s*@`zT6CzPmx<7EB51x}# zvuH^a4PnGIfgyygPfLx8l!jkf`XGQ#eM2YWZ|&kZse?ca--D}<8+V%=l$+^x&e4L<%>V{bi`J2t-GA#Z&Q7|75f zYFHfzp$;bEXnTq|rl5EWGP)*$FWZvnTgNG_)TwS&T^sYZ{tejmM$ zwsVz8f{E>+ko1f?xmUqX1-}$01$cQ0A2*TKC2hPshf@yt$Kr{pOp^!;A3##iZbZvg&bHBcV&>d8Lx7 zns;n}2}V@pNiv%SRJ>gPkdM0%FwEAA<>YW6a?pX&KRr>*5qmzw5qCej+A{I5{a^cIXPgX_@~^!`rVIGfT$|%^VjjIe z9Lrz(>9QA<2dxai;d?=ffgw4*TS(JpA;`WnvNMekSC2H1MMky8~D2zhj|{Te z!;Z%=T#K?uhX$P@Zqj{IQ$9qFD}7IT#U|zyDz^#vyG9Q~$sVz)@DR;g1X(}ZoS_$+ z&C?3MSfHPbQKx@W1u_D#xrjoISg(F z&Q~IxBfK=;+ZJmyzj3rqy>C};0EJF*-HPm*wkAt#tj4%FIf=$-vyhU`Ygb6+Z$&0R zuH;wDSerA6aWIu8hh`K!G=roiJ_;A%96btn)G(xf0Js4h8GY5Yh~mwadt4)Pw(*}m z(j_w}jxTLDhPNPxj}^ZH(-yn?)STs5Jj;xyk*=k5zJm^@BP3f@!^GJ13-gte^2;1m zzTZt~@q;Or5$eiTZ~WN}3KoDS!CPYE@7zj=1S&V!`41yj1S8kBi1k*DHjh!GZq~OP zW`5sOk*g*`8E5OtL+ocJUkz1J+0b-E6}FcIL*6e~-^EqGvdM%@qurQ=6{Zm`m0Iw4 z*~I?c0oRq^p+YA?RUtMU+c&xnpX%9g(2Z1%!Cc3gjw&#;r`y0s!30L7~Lu=o!nvkWgjO4foNdc8lgs9FQ(kwXYCWjJo z&uhkUPq4YQg*@wC#_lFJ z(;gn|iM|!1m%NN&`f%!kk>%OEO#wVl&;X6;&T6Gp36g{Jk3GH?&aYvN)0eQ>#}3h8 zSSdhdGDQ-Xi}Zd(6cYG)ss&x_SlaTM5Y1YmM3rDx<6zvNsUNsMG9;tVA|pw~Rd|#$ z9vQtX1ggt?FOi6Zc_bq73AX>Dj5><#TXSP$5UJ(DWcL-{(isqquCq#_8rs5=I6P(???CGG2=JD)2zYk-{T(a zzTQ8e6=8rsM9qIl>pqS-U0Q zvTfTox@_CFZQHiZF59-zr7l-@**2%no$t(=xp(%T{F#|+<;r+=?AQ^$Hf$29>EEiX zvfqhhn41aLYKF%MKS(FxWMw@mo=N*_OXIVEbHG%jW)kWp)h!(>W(Z(`gU?YNUlOr? zz=|gPWx1>hk#_(pK~L!vbgB`k=zG^So;Y!-z8M}Ogo9(?U^7QcAWAT*Tgrac*@2!! zhn!U!C~8BnM1~P10Soba!tU%Ucj>}LX-7XI@0?77r5d)|@t9sQjf#_zuPc??>TQ>X z1AKI^kUnP26d&tLucV24Xy8vZpmf@lF*!nbXDnfsHf6W_;tf`cUw6?qw=p%=Hza<; zUB}}+h7-PLK1K3BYKLA7%4Povc@DbZcj?^LoX^FhCXk9qci-FT)5o5u;#U>ntHBZw z(s34KmeE&q_CfLP6({GvT7W+E*Ne$>Cp_>3B;8VVtOA<=Bv3-km^*Ap%-%L#vlY98 zu7Y1Q69a(7CW@<%)7$f3>G1YF_r=K*yWuCy%D2HJbd#rVI*LB&sh_{I%|0IdH1EsQ zlAPl*26hK#gV%~TyO1=x10j`E2$4&A3zw?Va#qlVG1ze^e+8E9XXbWFwrqF3t=|@H z@yMMWp`-J05}H+>o;vYS^;`6$pB;|HeG?L*L_}JdFoMGd$^o!u&}u<~6EfkeBSZ)( zJugm^TTUIT{x1i?vVC@MWs!wf{0WriyBd=df&6|quDP33ZQ%C498EJ)Ju8XpJd{+V z4ksi{lmhd!62*$pNZI9AbJ>prPwi1W9NS9<=*zT0P>kpZ#%31Gr(EJSWCFq=;GvdR zh2TG#RjA0Pn2V?rkZDOZWa>-6zZVRIBdP;MyedOJ^iKiZj{Ybqpu>)VyN~VN6ywXkBBO%c{p4JCk8vH&teZA4QB;nLG!~9ZS%F(n<}JmS z*k}pYq&ys}>h<&q#w;R2KZkBgG4KtsVju;z1s<&Y<**$f+Rl>`jDa>ibuBdEe~pf^ zIe=TED)4tc*Oo{Xh@)yi6iPjf5kyC2)8l|VBH$nykYc5S#XFBI`Ce}vBP09sk+;Un z<>)Am+J3#&!BrA~xPli|j5Uq{=?ij?1epXjI|wA9ApNIOKp{v1AT$_83!H)^p(tnOkQzJ!i4uI84{>cI^trmmwgu>#^;r0aPrqizOjorG0-CkS#|fn%T9T71&*Df!-}9)Xa^`~;2p4s;B5@d(yAWo&u&3?miYtFlKJ@|qoANz zX?A{1OwPg`n;H7FelaB?2;R4KmCnctcwjt$^!z*#JB|hlxspt_mt%W{{d8ItguFc) z28F6cI!X{CMsBd1#oT7e=FX0jVn7shZxyAP?EN`-(cLSw;w+jpbabOY+G)JcFVV&>M z#hQ>y7ZrwGqrT){)NPygJeoQ^AXQ?Pphq$6R3(fCpRbyaSiid_R@soaTQ1U{-{SPh zM9%)enc?}xONFaLd*(A~QV`aLLtGnXmX@DZOqnCJdL){px7z3g5v#zN4rK75vhRMn z^Ch63Ks&q=N3xJ-_Bxzv)d!A#TzC%5u^eTxbe*6RMZhgBOpK3}%h#<+vgXn-(K1srbu{ZDkz89G?XatjcP?1LY= zU9W2=+cR@%%i9DLMZr}UI=O!%pS@2{{(hTRDD&SsSKWp4JKtW{xZezj%%4r6d>q`WO4_gy4hieR9b6{d~t4P2Z={W83HpIY7Se z@nr5};-3a@ZH#C5{~+M-cis%zb1^a;8Sspkm@)Q^ zEBo1mKXeFopWm)(gze8V&s{0O?QNyf+&9u&F;6$t&Ylzwx69D=_~tb{yKkNh8JbPcy4;%5yaW|b|K;o!Sgj8lFXv^#p#Luw%uGWP=Fy~&_RGa zNX#@~L6?{kXB?AoieQK3fUNOU#DtL;hgsO!()B0ks%u9e({njh=;Opkn_q9%wEw~N z^ESU$$^*_E4mAqK@y1m)b07Z3GDdQK4kvPIQP49q?d&QPP*~nf%T?dv*?9f zv!Dp9gOZfzk!YLGleH>S{zEd(*wlmflksNt%G}1w9CNlTFU#EnNOF!2I%usrxLew# zYYs^r!ome3>u`JhS0zhd}vyv--?YEfJ+>K1UM`L~QZ#|gfuFLzLx2lI1Pjkj1 zt45BFn_arf@;fI-@4w`4kXvr@5mk0wxh++ywB`_W4L|8Xme>u-j>((oQk2?wDqfd8 zv0Ba1FiOLs@oQUkw1Wae1h-8?IVfp=T0#pbX~;wn0r>`ml2$@Xo1rIJN(3Y|JS8-; zQG>Q48KPLv-`yotwpJ4_L*#PzUn3OXsDO(DnkUgPV%iVXj9 z#~ni$#)}u5B+CnNq?rBk%yM!WpAdssK+YL7*+x zRi3TE742sXyMWw)H6W1)4DE9|tNOjExS#8!Mf8O1bVaBlp@`l{sx3?Re3Ih30ri&? zo`%lA34!MD-_0bIH2@R_`U04iDhExXB1lwJqbBhcZZ%*Yv_xZX<~hC7e8z!P<(_UC-E;FM&t7^eV>B#&XBc9x-0z~JbY zJ%d3sfFnO37g1J216Blo-#MtpQeYjttPg>>6SR1Vxo4C*$CK zO~CN?k=j9bAQe80_{~m+aSZYRRTq}A*QEl8Eu6SZ!Wg>T|o#6OE|v(F2UWtaj7IC`M5iw-dcbGM7xNH$+=+d*|~y4tBP2 z1PEDhR-o&#Qa^0wn^0m7qbP`Au@-OgvQew9{l)Q5{U_770Tak*G9DqFVi2L)!L1KW>`t#00jXq?g|2pEa31|$2q z7pNnYAqNTC^g|@UEP*mJY_H*3VXNQhU2u-NkB)0-=OeTgff1UZq%TJFXK*VNa7<81 zLT?eQ(>vIzGH41-sKm{&gb`8Gv(Wr~4kPc~Ie2xGBZ`2KfRP9IS!u=z_=DYqKlP$UDcaa=Dlw?k8l zasMqHp3eg_*Vn4Mo(=xLRVVU*>p2{X=(n-QxXX`cm#ahn`~3m+uU)qXmsp>J)yt?Z zb9-?tmw)L=cOZV3H{7oW`Olr_{60?*|I2i~z_E?pHBmp@eukcZAg|#c$g}ss3Hz6# zyCs4ppn!w27VAP72y;;|K#Z|KbW)OYVwn<}HD%tCo5mu=MT`gom5&WRX7MqDogt=z zqCD7PtGI1#o{G%HZb&Ym_dbwh+AI%#9uoFmqm4=`6`b790rsLQJB1i7*A3F$)|1Pg zvUJ;^CA=tE(e<)i1+LGLlA?bK!Wm5+k)PVNJQd((kHf~oda-q&;@-8Q@ARo|_ljv+ z%{yY7IVtS&w4;zj25FcWAuKZVdwBUI!s41+`<*20t^r&Eu9OZY2d9o)F-p5Pbn6uC zVSj%6KBu`q?Hk#Y(m|uTe+U4ZHj&_lQ(x#+34jNteCwvKsLwVwq$*Dqs+;8>XXc~d zs8q7k_*41*W9|Zr@4pk5%*?lMsfxgOFI&?)@}Ho58Sj$q$ovckb3@v7+gm@{-|Cv$ z^Iw0)X0D0u)P7DL?*3xfm}fy|T&a2-0AwOdI3IAFA&r7EW3JxLt!ZL^vUOI|Uaf;4 z$zNd+W~|W<*_hM(k^{HRUS5Q_@_AvHd9v^Ab$2+U$i3sp=de@CeQ~=ZLEb}2d8lh( zNGBBnOfLzTm|_2_$+NPWWsmq9lk3TZevn+wjsMCc4*(4){2jDb;UL#f0x5F4{cCtw0zmeY{JaPQ&LOQi z#Y*hMtjD3LM>JC|k6zEuQ6A5}_3YB&agd_yVde*NcA41~)relRHFT}{q_W7tJiBXOC*_ct=9pcL&JxD*=Y@ES_g@$9+s8BAmfn-oK?TkPYRwJIAmY%1 z3K)UkRp6$!UKv?H)t#4;=qSmWsV02E=HSE{IS`y*6`D9mS!jQ7+pj_E6PU<4JrZA@ zKV2RdJR!4fdARc3Zfp|gmsGf)MI%q#w+HqX*;aNSIXiU?)y&5{n29z!_pbM2u1h2} za+?#R{vHYl08#Otv=)n$m__Y6tP8aL63agZJ*Bn80;o}y5aPs5iF z5pX1Aw?V65?eZEC6ACCv)MHAL6Q7fh_Da;k&jK1{1Ij{fAMs(qA3vRZccsraNmxYB zwGe?@5oQ5X#^+g((ct9$sr2@36ByR3a+M&0%6fb-eNnBdl+IGRA+2Ypf1A`K>ph-YvM7ApuhXOVMGy}vI^0SJ=pd7j1nJWypQygwcC9vu#jFbUB4HH(W z1{y3Gu@ST_iL7FKTH|K%}1DZ1sBoKhd% z>r7*(!CmdTu;C^P4C|w)4F{ME1yk5@6m^DBWKBLkL0#uvbY;dR#@6kGEj5L;5mf|U zJ9QFMYlXG%X)8(^@v~EFpjM3Gmb7AB<%nbONP}JeHou!Hp7QZ2A2^cZ*7=INjjpDp zg?gvEd1t2&9MOh*!x^u)JS^1R%bC7bp8pHW;b0yYP{pOxZvcwNE{w&!$O1A75)S#> zNLHfDBn5@!DG7^uaL&l8X>c~_j{-!@lyUmEgCjPaA=doousq1Pk@BUs+2&Hz$4s3}#WS`;pGG zXspiS7FYiFTF=xO6z(0zMOkA{QNpOKT&q0_@9Y} zYIA5lM>ZJzUh^Th9(TO1F7!XRlw;dplb6hU-IR`-cxZy-h>!na1^=llLeM{BdVB*< zcnmk@pDXTr(ej6L^tY0LJ|5Db&-XF@!GF8Dqi-+kKB)^(a3YGqe$8_v@KQKHe+jNg zPD(PfGRz)v`ZX(YbY4fNsc^QkaX#40D(uc#eQu$fKnj@j;|oaJ($Me_=FqDzy1yG$ zZau9varsu_;cyqNbSW(WZjY#m2x?A0QVu(Dgvdm5g3?~RGRH$46eo?1O2E-$8r6i$ zbuJ=&pPTRduU?1fPY94+|89DWaC~jMDN+uTfdfbz8w;XgVz;+`>MGb|#Q2>Laa1PL#pU&%W5fS* z8KVr0d$-%yPUNqP&VQdy2PAlP@^`!pmVd_F9q_{#+#+p67ux&zIp18{m!JXz!mu{x zFF7ELGBxGyrm->MLiL%A6Ex!>@lLxn&sl>58GmZ0(ZFcVkoNC`%n=66T{s5F=&odA_6&$jL zwnE98ht^>p#^%)XxAU^7Uee3?x;k{*&N9?{KDV&ga?G@ObSub~kGRrs$drZtZIj9; zP-BPZ#h|2=w&6it`u4UWoTVir#te*{pv6wnRMtoSVN{o*MK44Pul#2eZAFB`)6(mT zY$=?BC{)w?m!c-AwCz1DFz|rtqFND*Z&Ss3w7Bz)s{HJ?=a{dJw5;N4I&U4zExgsy$6ffPh&qTt-?45woEl0iB7q^!iBn049VTV9`gLZNbX`MH zyNhtUMZn|PDS61mo#9g{txPg{-4&n?=fv6(*omOJ2xmAY^n`453zece?%!FjYdZCD zeAd5Wfzb?f6Xp9Jd z$@PFI39$lguvytE?yy(4^uNY9ICcuPA>Qi-iHWk^P?~`avJ*ZIMK7RMhNQsyW+T2u zU?K;hLQU5fIE-wsbLaky26pR5cW{Ms8j3+gT@fpwNP!TS@C`!ksB)JpVlAP^ph`Y? zH*gD(foa!-ViVTl2*9>7b4f%jCbkM00fi&7Rue+h4}ytb{bpP+o7qHco3{CCzReU_ zNL+Z6uys^{BqV$V8bx4#hCy0;O}+u7a04HLU=bUdHN^e7x>z3y(=%dMf|&m%{%*AToKF<%iT z0X+CO5a#b{Qd}i`S>UppEEVS%$iv<9v&>-9A}X|S>AGe{@={P@x6Bso*%zH0o1-qo zPCtg^sHFs61L)F)P$jr>tYPt^pSliB5a`{}*>Pl~06Lzhb1TtKUfsmV2@H{}%$QQ( z*=ipnl~q#gL60>Q>X@L6oQPBhW}_~t!%`u*SFnqq#6Yyg_(h>Tf46-D zn}FFFj4%DW05Rwcnv-F>Uzrii_;+Ky&^V!q4!1Fb*fcni!qxNx6gN$5E-1+aUA?7+ zGLug>h1j5JEmusK&g#28`pyJn_XQB`eRlL+@{GUEw-b3`7XCYxndeK#T;Q>sqU_g@ zdf%P+XT`$@5lw=5<$R$hxlbMJgqZ9aKCR(aTVf0*e zLm>2*?<(mu)Exy*fUr!@CQxE3`Nb9RqD0F!NZ5Cn#6Kd7p5PW)J|1N0rvn6|Nxz%( znn|WIwZT61X7CR^*%k|TXU8-i2kg8^>k%fKcT_SxHSZ8P#>jsdGH;hb<9rdj>y~g9 z&T5JbpqkUfzU`iZ?@Bq?+)!dr{=tw93d>w^v5?EK$bX^q+?|!4ol}pS-Q6oVTwaf# z1+|*cpChWgz=u&M5#~HY_#I!O6wm-W186*s+}gaVG|W4+o`L$dvd98vl`8ljV>l8L z_5addvga)m)k^1g)tN8yGmOXsgr+aIt9HJUdviWDi94SZaip2v^Rt)tzNlTYQFJEq zyB_p#V5ky_%*`9%L70Ip)9}_}8gV+CkS)w(vmD`hmGQI0qp(VCV$B>~SIL!Yo8gmY z>!APvrLwU0mF;($fBB|tpDJ?mUITMQMJ&?lPQCSe#iMcb8%Ad8q@VU1nl8*fTuhm$ zQXg^%wemdaLbFW(U#=At<;MJU-thJ&Xwu zPteSaS0xTy6iXmaK_i^4KLK(Ai$SBsZ@3U73hD{2A~#ScwADt083$db?ni1k z`O{B1ET9U+7D@z&?4K1T5i~YgHaQ2409S>&ak*$Y6A(?~nCO0S+F=D%mV(~P$Wmxb zDUlW5&lx~v0xu~GECZM!xUsQfPKQO?8vNuc%=3rJOHqBLNJ4zrVw!WrO}RqM^f2VFCL_!A^wU{Wre#p+KI=%NhrM0nYE~$7 zYqr)hdu>#1UDBj>PXNh9Ok82g+HI<+TyQhev@T$TQJuXyYr$48Tm?( zJ_*{?QaZkRcsiUt?n41M>T`3${%#s6y{i_9N`OT*pK@@3@h`HXz#+C4LhtWfekHd-Wl@S6R0;(W^4aByL zI;})19ck(7bk1?q28HO80b~`%7+vp;bkPdp3bln!2?K6K?AY_0RJk$=pLQ@6W?yrw zS>+KJnVm5c9SS{ZZD0`XuA^nDw|uLa`#o3hhiLHaS_Xi8^2*Gj{+cOgaN@Q?cj6X! z=J3A8&HK|{4x{bUL2>4j6NxU*JJ0;{+{N#nzxTC*;HBzFe&?-iF3;zVh>tShGDHEV zcV|m)(f9wNC-+KFN4^Cu{$TdFwKq-vPi)5!JDyAdUw>NU{VzYY?fpLM{Jq8gLrmU& z)j!cUq?xRFZuhOMdy5Zq9r4|%YN}3Do*Fd~ESp4^m?Xhv!b#OvK*3?p3lspsq`?j0 zW6k&HL4GGTQD9>-!+QJ)G}LYePcvK#g40F@VwVhT6p5Z8k3M(fk6KnueHfp9)m&#( zn3a**i!-!Uj#3jWV~u11BY4$7gsm5SoB*ru=28Tq4I?uqiVeRLts2>{PJA&N6HwwY z(!lImsPMM*nG5eJvkoUaEM|^pw#zYwv*KuiVhuf?%Td<5cAxv;R=;;b@6Xa1vtwD+ zp@GQ$h9Jq!Qwu}riM`Qk(qqQc=lx(7U4Bm`kilbZFc`B_Ir$%boV-bU+TxpZ5_^#M z8!ZWGlExrHB#0Co9J@_Ily>LMzyUcdyAv##Me22U>PQ-{ys_Z3c z5#sQ&Cg>Mx4Ek&2O$h|uQt~xZ3oeP8QGw%8p2Xj&Zo1`FQ{-I|xVVr3`ptw)?8@v! zWC#(Afh-a!Rvw1mZLM)espA@d=Q$}yI8Q5v96UW>7JQ2z*T76dp%0CVYZx)oo^B!^ zdD1KV^Fz9sp_cKol~NcuX_rE8dw1^3B7O?>8s_Ua5k6iot7}4SIE}Oc2{gM_Q1PD$ z6qSm4h?InMr0*s73?OyZq|RcrLR*EfanB9mJ&D7ViSIzj`w2#&kH2)Q*BPF_l04$c zG2MO@lLnzc^cP!#RYIFp?8H&Arh_I_Ys?Fn_XtEU4KQF9fS#eeR^fHbCNl~02(N?L zD3{^sBJ4!~vwZ`u@~s{0$B^6C;3O#x4-VW1IoU6mAEiORv{47$LksUZ4$3DeUNP z7KkRc7bC=JC!$RY3dD6{O2IXp_>%>Gh?xQdG{RcxWtrUUPCHgrdyi$;paL~8X+}6z zZ{}%T&Q&~2H!yFZmhy@0U_~jGh3wM>99g$vH_oWqZW=Cz3P%

#N5dsj>K$ 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 z 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≫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%0DyNPvnuOI)(lzY~klc`g~O~9{WBF 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

=q!fSrXMq5+6BQMk_(5VHYiC# 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⁣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 lJIl=YQ+gVI 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

d z5J|tZ1r=W%^b86BH5Yj5(AcRzzk5Bq{maNyRnVaf_xq)nE*WVQ0_d&SW-|HHrPb?< z)*xO2H&Vu(_r55;Zb;okc=*=EL*ix+sk22R$zTsb1B&pN!yNluJ^c(OCFlv`_#-c~ z2m5Fag}#@+T#v`l0&uTkbn0(O!=Xbtiu@Xs)!~XtGPJlNY7>Gu^|RDUNcmF5Sf!QJ z8}2U$8{H(QK1&nd-@rJafo+&IPWS7@P-U+_8P#;xSGh#kWa7O)G3d>)x)bj`1qyOtOn=9KG?!Lfvd z;d;`fCtopQls24*RQ_3Zn*CT+`kCFMxC{9wyLUt zBow5EUue8UAm!@C{i6hm zN*nRwYj^g}PSDOP#z}32ua9g~4Cv$X4~SSM@)LHTWR}!1WO!J1mJCG)VWUZC^S>ZGfhN+~9M&N362BaZWX@ehM0Mv7ezrlZ0|BCQ zMW&mmaT9@o_clTB%?i+$`p!rIpf< zitMF5mJytjSanQz7}X`!mNYvZh*};QZW)WmW3M@XkNG!I@b(Hz)>W=j0J^t`=17&?@e+-fLj6X@x)!IsQuwML(s z@mS9!c{0^)ugB?AqWwhB_OT2DBN&wDB_neIar^TKSk*6U64s`-Do1O@d8hkicuxcz z*lu|rrmZyM3(gSLHWjbHAJx4f8j|0z->=e-Cs)RXZ3Dzm$awN4EMbGV!1U0wc)P4< zgGrY~#g;?>41jVoeDbQX(UY>GE~t%?sf@Bx%CoMc5F`ZJegy6AA6T4elbA8a%tn@Q zbbMH0KhZ@ZH~K+B%~YQ4%(AHQ#178%O#P~QcdYrN3ioO$ZQ`XpWdTT({`2wlWE~KH*vk=J^79l}g*w0`7gPime}*4Z{<&CqR2lGeb1*mXbb0SBzRsa1 zMKrzJV56eAX1re1R-QH^1+cFy4o7O6vvc;meZ1&+hTZJer+2Crc04`4i8uz-&($<9 zulirkxxISsU3rOrx*HhKKYH-|R2;MYk47qVi@2Rc9X+5Xq>srlbRN~* zA*uNmb+a&)>x#Z+iSE+0&<@wbUwXvn@P+0eagfsYJk+G~iJFVoEHM7VEQ%yDoYt>a zmN2dd$^WYbxIevceciy_I#W`8xT!=5I0-?pkc)Qm$@hK6iQQuJ&p1cj8T-MpjFDbu z@=T(SL5T#j9(aC`rX-l~xHrTmnGGwOqTQ^IVUX*g(LI<^_1m^Hp_7{M2f+*Az&oDUe#;M*ueTgAS2{537Uh6V$L zUqOh>8WT4Io&qMz=1NOzg;5)sHPIy8#X}#-hafN;g9YzhVh~F_-scnZ4Z!7@8YJ7g zxF4(f%R?O7q2J#V590X`y=~6FHZUbC6Xo;h%{`Gbu5FZ}_Ho@tRK(bvuk|n_V(HVb zs~jjWqK5cnLuHBtcJrHGhkicK^N7C!9Q6@5CbD@>TVC2F_*&mAkqowR>PmQK9r{9W z*!r;KxH|b4_UhoTs%s$g!$kntNPmjq5sc1kh64Oz2%^RcV=ucU#&8Jpk*;wQx_^1@ z81?kisegvC_KlU3G1xn*aIgAK^3r110~lRCYgs-66sc{=ZjblW&LFAlRkYz#p(G2v5%kj|5T3-$r&7ETy>;cz$ zL&&NQdSctEB?m6Vl3AqCIr+OqzDHUw8%lonzWIpPZ>cK(M1ED)I2iBaO#F}hN@3N~ zNqU*?>DeF3Y%Oj$j*h>|7>*+Tt=nJK=LMD1jgZ59dND4G4$ILaQ~W8juDMVwJKp}g z_X9x&7JtOfgXm6~DhMp2&)qOI8Yg#)E@RW2NiLO)Rkk@0Ony^2jC z?&pO@>Nvk&uk4IX4I*5aY`wC8>yke_R91KH8%qu(!uFmga|Hr3s6R*=6{N#J$xG+j z>!PBknG_~(n-BN5akl~{4>zW(FKpOD;wK_P{nyZ@&ZoW_rB2}-%76tZ0TLqSwOBcf zJ+|{|vK9St=3$!I_R8JWBpR)%D>RAl>bT5T2iubCxzY>K$?dX=_} zkHd9X{q`KSh-%Ia2AfqQNfYC}c;{xi<(}oPHXPi(Qw(v`PJdX<}tm}qZp=Is22Wjz|qSG>h!LC&F zqcI+jZJHL0p9+=t0U+hEluXO$Hn9C-{1c)^VTnoI98Da7Ep1e{e{(W;Q9b3978RBz zo4J_MM_L;ZMnzITa2~DC>;NGxkt4imGqX>5j`@4xfFxUzGck#?(-z+l(KMuG021&? zd1@T3)hv`_l4F-6N{WZyVy`B)*flcq7vbifMECUBox37`n>lBDEvtOPW_y-H>X>LggdR9)tKTfw}2HVGi{Y+&)N;#p(wzU#?;?*?1uLN^$8Q*DFd^ebhd zZq?e_@w+VsidVIXUhC7X_0^V8>0z_o)5d4=T0GCq#_UlNOT4&(essrLdYG(mi?Y{w z^dl>|=Gi->#p36X9t`n${+L1-0e_LAxLB?#*<4eMKXH~DP$mor!KwVROW9#2rm|R5 z)x5k>Uc(wOP^%%jwG*vFB>_f@B10Y;TEWmp7%^1Guv%0z$+W&hgnoqG4DRk_Z_cIV zbbbsyeYB5Q0JH0#ef-Jc=a)^$ON;!D5rMWoMSh1!S{XIq_Vh`#jN*r3#O2O@>UCN^S?3p9(=W07F|J!yKM7^W?H4{AzEa~q~4&v@LrvF)TMzJEY!`TVvuo z#ugqkVX}KMIxiA%m|IDmPaB%)^TyBvZ0chzl(_`1!X{*S84}1e3WUVRKStkf@pwKn$_t*w$DW=ZCKXIt9x8QP}KemWsi0l0B^tCuzhoG=+MSNWbQI;Y^B(v>^u`mAJXsQ*^24q6A6C77CuM?+9K)m*hhhPbDOAPr@>A8 z!5||Q*|`v{;9?lFsG;5WE{JMtF3IRvE5u$Ni;%}%jaJaYY-ILv>}x@1?1)z-cy2%- z=cRH_lxqwGj-vGW0>Ic4L9Z6Cb#IT=8+|xH&e)AUrYdl*K3)~#J3Md z|NC>sYvO&Y0f#>?cD~i*s3T|s-4p)Nv8FdJycv(LbOt?#y4=vUsqD?1kx?2y)7aMg zKfuYXHM<(o;Q;qt_I6+oVUx0|y;_fV+W>!fW%ip1W28QBb*C9>7k8BD_A;_o-rs_qO0n=bl?kMCHUnqXCq+iOV2B!Kj(-0u8($Ck{?7! zM*?a^I$xHdz}F!ip0f_T6?}C_`AA;gQ4i9(*B31V`JUC3 zC4(%%wyQbt<^#_ze-6co`{$D69K$W4Ph7E206;-jWLTNg)x|T*?P0#Pe_EV-mIkN? zWh${>29*9>540`Ajaz?^IU0!j9jn?EbA2r@@@du!BD$ui?^vM{UO4t^{mB49XW(BE z5Ca=oQm_F3uUXz?bSh>Tl*mhuDxyADSBP?TSvS^SGKyBU?8i3AYR* z6FHxElUl8>TXl5HcE|Dzq^~%`({x-ZrK+Zfxg+Ik_05*!ie**}5$)#*+@kNz>Po0c zHgR}s=iAB?C)*aV5obg^iFlsYeJjMIeO>niUgIROXyW2)stGLZ;irhguUg zPR;Mzgcl~)Y}6yMDv`_!W?lR9psNW?o#)#F;`LDu@v^B5Nj?y252Nq7`p%O2Lw_0O zeM8%X(bv^ZoDP$_+#pw1sqyF{hWjPXO1GI=p|_F&y)>sP6l9hb1g%QZdMis-=V~v)niw;+D$IUq#FPVN0HysAFy) zwTi5aiGMGl`|18X*M0dI9hF#d=O-*?ZkNRrS3Uy9@xGWwuWbK6l)Y6{TWz#8TwDvm zin|quLh<76Zbgb)k>Kv`?(S~IwP+|5cM0z9E?@edbMF6t-DL0mjO1#M%q4TpSz@^# zQAQzrkv!Te<*iP#uMY#)=SH=2sq%W7=nq>whEvI~$y-?PAYS6k?$yO#!yV@Q$0`E@ zJAe|I7cB^QfLY9?WMR{5eLP|FDFR{dIl{8|Q=z86N{jm-h3}GkeEx`_-8}I5yB;fJHlZP=sdT zn&NC|xhBd?*q%LI3Gy02Gl96t z&lM0MoJt9(r?DGb<_Iq_24F1!Z*IiIBO=<`!iL3PXo+J!#nQI4ZJ6;fL~2?0W|nU= zSy&Jl4>A=RX~+r{xmintsOXie+M6{9g+0~VxMLzK+O-4mRx4)a%N4(@Jtq+)fGR1U z*WC(S(Afq?aTu757s(LJU6lq1WpN_>sYD%rum4>?^Cskc4iCg?vBmCa$G53iJNxU> zalhXzS17594+sx0@Sjnhw2)&5a4gO`$c6s-u9|dU_Cvnf{Wo%2WK&4XQSo1Li=UVx zSkVK9b_DQ=WCWrTYQTljnokMvRq_MdB=I6$+5p@m4|oD{xI0l(fEFpiG3<<*h3%~6 zU@8u-F20$;EkB%aa#D;b3Of^nS+(M_2zUEluo#iL@W3iu zmlLO6_47cCCu<{8O@KQ)bx_`!nOQ_(brMpqy{-@j#(OwQ-mG(5&*KilJGidrsRymp z{9PLH@;G-L=#L2ECwViJ>OW`M@9@arytlOp}Ez6ZUC$ zXCFBatwOgzkpj7<-|eB=ko&EpVDsUcq_t{P(7V&~Q83xL`!ziGTJ_5O{YC!qI(l-c zGAC?S|GDT-Z1Kd9BBa!+_3NgKaKUKY-I$(u!Nmx0Gj(g_iY%`NF;qq^t$CKaXO+74 zytX*!qTk+b*UqNygIf8Y@hmX6mcR+Mvijrqpmw?bhn+#%!$y`zfQ6#|0BN_*+Ivgr zbB|LeirR19xwIi;1GeBz*vAV6J^ieqh4w#+;1l1I#kfB&-ba4 z<#Jvg4QFz4G>;D19pDmp#r+kHwix`iul>t}zp-{Xlo9f*QB)yjVSeCNEOVIWssXt9 z+T_qlH)3MKy~<5_S%rUxUVlDr-BZTJXX8(ls`%Z8A&aIP4F_MiZma zS>XaE$HyjXJiWq;BL$7B=Doe;l;_V0^7v{M)AJ&W=7-75&Yc)nHKSS)2;jElbbDf< z0Kb`tc#9KPG_-0VY|7IQ27mZ^u}Q3U(ll&G{mSq1ZQiyqK89Jb6e$c^iWZv|#O&Eh zt*PtG@@gU(|E7M}{+ZDAMa(=tC`$PloJICSBcP09>Y(*bzJLI6%XVu{*U>(@JeUo| z7*h;i)!2*6;rVjp>@eKY$E2%^eD_-dCc&2`j*;chvc<_E+G2?bA-~<^P+Ni@IaEl_ zrW!%z7Zza*z86yqk1XAfbfWY-RDUB?BaDR+F=`ZK%I&GmuU?r{@!apc6qhAQj-`-b z^e6O!P-05rJ>Iav)OYJ1q|#7!xcT+?O!RD@H3$+Y2mBV+BqDjpTF?xngZe+rOvp)` zNuf6Gt$w2)V|a|??p*A}7ijNMv!o`+oJ#WOVwT)un;6%3x;x;YZahMya41Cm; z)(6rJr-g%v%eF-i=rtH7KUHqs3qmRrKmt^!ss-M730%mIRYx=<$}=Qt;+z--?lRqUiXWjan6N znvi9yRqE9TX$(&{lcx==0`sd#tjjtCc?%hR+wuOVKiME4ZCJ-Z5H7AAjas4?07{pxhd=wiM z;Nsum__#=vQQ0ElUd5E$UvWZJv_VF|!K}ZhhoV3Phw^9NssQ2-y7e4{PM*|ZT1rs7 zL|ZZYr1qibJ_^2H3LzsB8~902iWek$2n-lp|L#n_-dxig~OWKOt^ye#!F$G`6*teO@ze z8KsnRCJ(!(RS@e_)DVW!9(NVgDt&(U@b$Rt=;%Kr4LdljzK$QNJ&93#zit?RH{w}; zTdz(Y6b7CH=eWwRT7Lb>CH(&$f`c^vKJE`oSbe_ZNL$QnO?d!SAAysaciXVXZ;w3d z(>kx4kDD{^hCZFIYrFM=e7NrvR{AFLoeT^P@!aLO>DLMDi2?SHx|ugCsPU0h%YyGG zY~pfp%*kiQ03^UpLJdqW|3SNs)+Z-})o&$NJ8Lh5zC&kxJ(TA`RUMC7`rR_C(Slai zS8*VEOW$Hi45B3wyc@qp%{Mxsuj3TA4XotC(uQ#FUIVs-X3#nW{)~O z=G^Y8B5{N_^*T1U8(byD9CsA;NgiT-Zog`Y7R%OC04N8jP^A~ogPn2q{tP4S+%nBr z=2fF$QWp8C)1tCcne&>xtg+eAkm&G7PdVVbmxYr{@#?lM1T2KKQ7VTiO3tUEr%5P+ z0wduE#i|&gd%wnP&Hfm4s5G79sG@+RDA?erv=3@xz}cU4!XVhDHk6DjXN;y3ddz;m zT5A?uPAuvh597)MURQGCzdN`HA2BVhim(^WjsNOFwke!zV1qeE%wzVIk>}gdX26kL z^wK?p8LD=)%its1`e45f&9C9To$hPIs3Nz#`<$9vVY6h5R#bMVq9txYqG-2<62>Bk zy_vW3W$r9{mY*184Qe#>)B?kNXfQ&W?Y+$N{-Rt97$xLa&AL+@3GttPZsDp*R7#b| zCUpLZ$`;qqz(<9q8Sn0LL~dkGc_5UDe7p9bCi(VE>XitQrdvUc?Q7sQ4W8@bt4BMw znuWKa=OF9q*}q(EP1iJ0s=5P`d=>q4RLM7TN@*AZFpFO-&i4A&k8`^7{KuD;w>Pp*>kt)ox z#^q723K)`-O6PzVDU!8stM4Fb&7|K29)9g7Yix4aY~}o^SKqW1Nl9X;w%q@X9*J38 zNg1;7w1|bSAcc=qkJ99D870mlt}6@*`hI#lp%I7IQMF7Vb+DC!XdB&Jv$H)nn2n5^ zKPxOO2DEI&?>7uhMv{iA{AZP1ijNfTHhdt^|3!5Ij-hz}z5**$%KGDVNMqmAA^vx> zzI;vSuQxiC7GhhdB;m#bbcsv_z?tQjsJNZTd&6FrnQMAM%0S zJ=>de_|XVPh_LF*MtaDMF||0$B6=`3&5>B}w`fhHf1Pijo3_iM%D@V3JMq-UvgGc}lY!pXP~r&z{OdQ>GA4DwycCFE)d<)b{3 zLpVre^qA1LXU#Pf1opZCu!)U!Ww0OfCrFP2I{eElhJ*MgWrR(Y5l|*#5^|&HVRbA{ z)L1afHkhkoLnf8z29$w9)`efq^)bYJv;4ZSZP`HcBTr9Ie6q5ejUL#jSRd&z1FhxU z3a4d^9K2W>@`8#n3MuL8o26LMU3xH8;IB8<;%qVRE0~q$#HiX^X!K>o21I2nqL|Ja zhO(pr6X3NbtZSLLijyZJyJuvE{W-aeMv4wjVrAlnybS0n?R~gsszg=;J!_{p)eXkH zZIT?C^LI5xayqrH8afR~H2V^RTKv5BhVN`bi+Q#Rql4B#TJ-5Gqa+4(dwK{QMdRs$0+V3@KSbBI-G-$X$?H;i$|AAwQKO)j2 z*G^P0P369Z5kVcJJR~v=E^jmKyDHMwvgeN7-BbvM#i?-IvgR-j;@LDTZV`Gn*O#)6 zYq$HW-0|4j_Z|D!vvty;*Piv6@m$)H&6cgXNCShEYr*d&9fHnWM4Db$-?;wA*4c+g zE2H~#?=Dh5CYt3V1aOX5K$HI!G%Q@V=5}ev%{`0%;vw@7?#Z@53(M-i8|wY*bByM7 zI-8$AJA-#?-xiM?1+6Vd04Fy0;D5)aHW82ewrgt$wm*NqSYN~WIUPY`l)dpvS_o*7JieuLHfEhsE_)=MF_!=l4| z7dsJ-K5tcjVigxjUHf&8XGb&Vzoo34uL*eGvUERJlE+ScpR=vgGs*s9%0L|k>CiC% z^};~|b*_zaL2UMo>^+aRyL;o0;GVA+&pmt_@avEIyFiD#j!_Tf6YZtv08LP)a>j+# zIO4ZsdZDNQtJ=^K*ln_)&-_`>ziy})<@QH-=a@ZobAIR5jiPB=VyEVfEqjC+@O4in z_N?q-u2$~tOA>cq&8`#=g$lP5#4pB?6NFhS1kFgb^5z)>T5$g0Tl5|+i#0~ftb)JO z6>`&|@hxDBD`5e`mkm_x=!#wo)x+F7J2880n8qqPilW4v)tg%R5X(;9s%Z%vPMjqI zx0R5l8KS#jm!&9!lv&$9(5K!Hs}4?W=!JA!d}-UtI`}^>KsBzy@mSD93~QFs*xGW1 zE%TYW8unPBCE`aEal}TeFwt^v5O<7-jL70gix|D-IiX=`jtCh5j`~M(N&+tKXGWd`#fPEix;!sda1Pj)o{cn1?MCDI~Rng5HI$t^H-BF2Z;L$wE^-jsK zVe540)(w7V3;Mi94YG@-Or)&%yE~teMp=e{JdLd)W@UI3SNXZ4WV{HFG}Bv;Yg0`O z@00HryPnZTCGS^Xde+UJ?n0ARkSZ`jH@~nrhii+b;=o;yu?9>S*rUc{O9!B0)YP^r z(vqYMNRl$HE-#v9WfxAM{>dM8Z(;Ag%gyhX^0^m#@c3PleievgK%|BkDwaL&b=C9E zc3UqLSVstS-Akbo5RNM>l3~VEH~#A83}5nG{_DE>DAVF zxE6HsYRIr;*Pv|7UW+f?fGJxFe4-SN4(&>^1_%O@gVPgYt@iLR)?^6w!QJ5Y`Tv@P$>?j1$Hkk!yZc z`Z6Yvi#5xIEZl1mcuR$aM(NH4KudQUi7NF6{(SgiY}%Kmy)wQ3^!oc|pY#rYjK$au zF{8#cA?Flmvs`82<8iQL$_^mcJ+&uDNUWrxGT-VJ1Pus$l#y$#?ydR?lp}%x$>3AN zeq`&o@v4%IN-bR{FS8;tn={F9#EsFbN?!hZ5eH9IQK&T>2oMY1M>xf_A%`Y%3+8sRBC zMCGZxVR3y4A!;%Cb14If54zw~5U@Hu>9NoG) z79CjLaz0GHc|G!UN!;pu=!n|YO#~aEd`3dYg`NZ%VvfIN5Pi}Xd`WtGimI+QNHU5l z((5C!UU!Kw=E6aCgCb9?QP|nnBvX*WnED{*1({n4BL;0R8e~4Vk!lY5ap~&HK|y?$ zED5&XZnQ|woIGv|FW>q*YX8=rc>i*e2`$ZVrCq>_2FQOEQX{A0r%DtPC#M32iy*q8 z8L^d1Yb=z}RLmQA+7O6PmRTaoi)9Y{NL{Iv<*2N7t3(e|!$6jTW1^V#xx~!4>Fc`Q zMk$=sVQ{S#dXhdCz&;`kis%jyTTDCiV#SY2 zUv{09LzWSrI$|iA&x9jTqJTZ;Rt??S($3b;5Q$E=zjv+U zu&y(#q$E3gns3yl=)Tc~u?et9S1%Bim2Z2y*{S`POBMa&D_$|R5aCjD#h%+}LUn2} zlaKwEP3H>djn~m1Bx|jazswb%a6}0Bc)eFK?v9MzTe{NkdiAt8V-!f=TDHt8-W9Kv zRY6?X_Gpbr8Ss^>Eoc7r#urKm5J-RpUMjUVl8@{N>!!NXPTY zh(b9XrISs%hVFIBeZNo3y-Wrxr5vV=_bV>3jxfkH*fr;KZq?A~sHgsk>(mYSe`Ov+~&$$)jyb0(+j5Z~7BjmW#UWe=lz~Tnx%bsWKWu@x(;^*k-OG z!1A{GtJzFYqo_cVAk0Jb>xU3bBzLkhvaPO$BMDR_>4@(gKi2_{TQ_GY^UHOt ztW41w=0-I^U_V%DRDTtEY3OaT0Y)h_Idqul$Pd!uh3vVsTg+Sc3Op0uui$}9UkwR) zMfAo{>Alq4_K^Gu`8hKajgiD;e(4+qa1 z_*PG>sYNX&3&3TbR`nK8DW0ZTqf^JZu*3_X9L?QJSVOM@=GTv=;Bk`H2-agAAhH|b z4V0jT7*`!$mEON+_AVuSAI7~@Aacx4Pq7Tf=ZJSlNWL6hj zidD1fN!Xxx4PrY5M@oI|xoV~@ATZ12Yx?8Fi)qy#6Gi#s~&5&b?ZvqQA8n}a@(L)AYQPs6knoOwr;-6V5y z5dkG<$Do{Xa2*{dX+DX8$Ew;^rpFB1sPh*xzYa{J@a1vu9xfB1{)NRr!UU?C~us1ZR_EXdhF**<<-Ilp2hY$ z>wmK-6h&lo0)>9JmleVD&P$aPU-xd`+nyw659wIy?oG(>iNbnIFVKzBY1%_T=BRi` z{csqkUmhhcWkBYV;8P?hv03rn@ZJ&Df?Tjc^&FlN zZ%aGLj#sDR@$-9b&%@jKfdCg0!Ro6$WJN{)5c{2RK#y2qf^@uApj{y}Kdbv~F4Tb; zq4KMDD^X7qf7jc1GI(vm5pRT+G{lTezIFwRI975BAY8E5%e}6=(of!9I^m4%KrEV- z%Qif6ek$09COOXLNQ2cktk1CSQL`$DH<3gCzD=6-c(5%}ees8g2l`gU2{fF55;C+pHD~ltv zfjF{{5hR5VCKNmoR)9b8Ud{tLrhh5EmV;($9(4ngBTD?82uye&S_sEi2Wt`1GF#Om zKLgN8=;|2n`|Ww%xj!bL65jsXm9d(bIZ$08J9utFf0YTyX$OLjtXo8=^Ol2&TycS_ ze*!%%nF-?Yz$7%w?l|7d!Tpy>h+MH!BSB?50Iys#zuqxe72^ph8l|~ z5n7|ZTZpc7%&!W!>_!-!{W3-3dXU_}Nj=Dnk!jgtst4rCKw3bURHQ}hYk5D2sr5A` zFNSHMHdGZ>fRcu>@i6gz{9sLSo2{G4hyoQr_UDI&F5D3Db&FsgKQocMF@v!FjyZqj~$S-0h z42Hw4 ze(IFDHAv4;YDhpK(GmdxGCuMy?jJKU-|5Tp$(7DYF87AB;u7k`FL(fh=>u_Inp67wr&3T$WwI`|`CY&sUd^4a)s8XcxqO1K6A zM;M3_*wQa68elYbp;0~>l`1ogAD+IMT?%U_hOru5I)R{{sY){L#-^ipxx5COsr>c^NiTwsWxQ^5sUi3hTSbG64AIHSt^<>%r7PmLx4Q}rKkU{ebk8v)fbtixGq%LWmgxR6@*!Dn4_ zXJ9EAZ@Z^*Uqd9sHg0F4q=-4J5c7Nir^E@I!_O7z7iy(1GPmeV7;_wcFWzTS9^SAJ%53|c=T*5Vou_E`X0yFC_G)2GhDXV5*p5$K|gDPIh_1Q zHN4f-d_=HQBOXG(oOobs$HtAdof|2FTP=6yk~sfYo$BGT0dFH*6l8uctKa@Aq)JiA zK}AqwkOahvOg}n}N4@uq=Axa;+LM|N3v-%;b-5Hv7)KiFJHzgtKOpwuA*gb@?=_Tb z_5D$HIuS;f(9-t=*SocHVDcVlJ9KfA;h}#yI4S&m2iM92Sum3@A=NhMqR74*0AmPS z6f2!Q4?=TLi8-#{e~rtUbZN!#-}UlLR`KX+&WJhpy_UE>(9hI5#dZHp_$dfa6-W^T z4O>*c^U5KuA}L=G5X2=3pBkB_>(czK3pq{yuA4rL*LF+m17mBun<|UxClhDo-!MO} zB;cLo;tqV)lXWz!a zbM&UU{(s`Kc#lbQ?rjHBGN3Q?M3^o;OkY3=lKb1zoKnd9HEBRmm8?1QxQD)X4Q@GcT#p0CX;j1Ch@>PGT0Yl5?XSm<%pw*S?|VP3&j!4bD^OXbB)kQpu$^6`N0!%67N>$)N% z=XLCx#l~&5at-{JyD7Al^INWOvwcpqW4MjNv-|s+blh_`-vC*cSSYL8;qCBr9{zfV z;8g`xjWhWNI7A4|wueQ6oYq1<48tC;QQ2YONJbl1%`ufy6!&c_&Jwh7D8BmL*$9mc zLV9TFPY&iSpZ5C3(r79UibBPYR<7o5q^~Alb{gz#E|1W$xZaMvd(5WvkRovuQ4?1Y zQYG^N8$S!JPV{zS8|Z^8LdYJSg1)rG;f94b@8F2u=+fq_*Ty{NzFr3zLRA%s=| zw2)^%z@=3y9s$8wK1v?^FIt0sGO$M<94`AslZ>}T%8u1n$z}eJ4yaqBsIXG`v|?i& zFgD(0E-ZMgy(KtfdU=fd$wogMg*omTN_ggx^@%^?tBZ5^k!$GbRyMV_a)-g!-m9je zYkIK~vfN$VxSQz^-%y;KMn5Kg-_*G?f4x9S1+TNjOr)NZuKE`pYM?o?u{<#0r`{jMSi?O~`BA2s0u7x%fp% z=kPH9T$Q_~YB#<^u6#aTL@Vh;y6AgM2f=!=t4PWY1NYFUOS#842)2ro?mILN@~ojzJizi;)OWE4iutAsd5yl8pn<@-yj9f4Lri2qPYFqHdPD)4wyL_Z!vQ}t zUlWCtKn31mnfyk_}q`y>utu57P``beGxz+Rq*f zUmWY3EUPEyWqL6_S`Y{`2ve}_cN1HaMc1SF6l1u;5F|Bfj!=cEHz5BCG*p5yvww4< zh)M29t$p{sTdUG+*c~~4uExReJSQ4gQg5-9*wgZuKW3W65-<4`U^4Y zL&rmJZZAv26oJq%0oh^zBbTQVSH}|7xmV>8YI<8}nARwIeCe6epjn}CV(Qo{4Celh zKsqg@BS@d`3%k!Ht*6bFl_xv^_9m>vuZ%+PH)MvUu%B2e3apx^*-mc03$TS{^g}2@ zVZ3*Bx~5b?wwO#=O-G5LYzlBeX=+W++*ht34tcPUU8D;02jCP?RABZflnEwSHI?mK znd%2vB(eSke8g!S()SV|5eciWfLB-66|HvHV0SGlPTlKAVhNT<|H>`0@V86la$}%I zI%F_d$1owMAb-vd#HRYUo=)}b`>PB4rRkAZX~H$t*8ak;6b;cvm0v9lYt8`Z<{g@D zI|}_T*OB4%1U@5^#hhRM;C%n|(?#SY9x#CdR~94#@SptHl(L0M!FH=MgazhoYB!hw zHMLA$XE0>Z3*h#Ni)GYG8_QkqB%Nb-a?{1!8K;i-f_Gs+!l%C_Ls(lKNfZbLI1FZex~mukCj zSGdU0YyikiKS-dk*{Ur#f@x-rq|CpfF$J<$@EUD3_H$>&QsJ&*09{=NPG{7VNHkml z$y*gha{=nBd%z-Ue|RF?-c_Xi&(>Iy;BXtcV`Ny@@&FVEG%{~)r1phvFzEfv$?a0| zIkNQKnV|WduJ-EmT?MiX^}q6`1`KO;1v^i0yCaHQj@~BObuIr^c(35~2^C-Pgw0I< z#V&3R=`YrCUTM33H_mG?Z}a`hE7V^!i_!0JSN}arjpiyk278@%tmFHJ$h+AP-5X=R zLzE?a!nLuU|9vjMq)nvGw_lIE_3Z)S>9t;OAejxYZXIr-$~5lClpy+G1z{0 z?$V|U;mj5x<*JKS94#a=uKG`l#9hhQWxPTH|#)C6l7#^G1A<11x)?YUdlcRTyKB8=$N_v zweCLA&hK>r_Pyl;e@~5Vd98h8eS$OPf$(lh zfT<++*)C8vn;JX)ze8CzJA92g?^ho-K`0Zn8;Ob#5vlX1g~z!^gwBVeiz&mh?Y-#^ zSLWNR_B%!9Gb(uD0eo8F!SF4o>u@61S))7rmpTy4=F$wTt%2G(pfhv_# z&Oi2UI2{i-cgo3tG|otDlT=QBGB>V2!{fS^!?8p#!F`;1ws2^3c0cdeKFYeJ7Oj?w zm^BqXusU&>WixiiKzbdnGAw5axv>!KTupOADu@`M!IA+erFM3rGG=GsNP{&3BrdW81emGFpdKY5i%=xV^{Dqb zfU;21fAiyn&?SUKF-1^|s}>PLuZ+fg!72H}y%&Y8WOpi}gK2S^mtka<<>)d+28;A^ zv_QY^-BRb?zM0wM+&j9;o&&$5AKMsZ8di%Y(;(Z*qf7O-vLB!n5jxCxs#e?+wQ`84w>}5P^cQDdWd+*lGw4$o z*umlgf=uj)cq0aodpbS{`uQ7h-I&^#ClQ_2s>Rq5{{X&NL0;yx1=}$p$!N#_?21q%TSTVy=PygFTlEegU$g2H6}{nt za_)rC!^!f8Q?C!Ftqky=AK!#J*Nn2_(lQ42<&PMz!yQ@?h;Ws{gM1=g^i-#+F#Ai2 zF$h{|vOY0>CU4$0$oN`?oR5;E6Hag8v=#R`vcS-+10`z+DZvlkHn(TzrZ;xdG26Y^ z6DbUyiayA%Wd8i8)ByP=1(W^cDE}P4=_W&_9aWw!2$LGCYdxtwQ0HaVTt1q2|S~zMb+w zQA|jkTO`?A85EDRu+NQ$ZJnPVEX{IIqj4%xplDsfkCZCdr@v2)559Jq1%+v@D*W2P zO{8uc$Hb!7Nii-N2MIVKDVG0f9AstZpz36lFG9^zMkM%y#Z9^WN(^Kdf>WWeSZOJV zsK_JiRZNb9Zo=D1Z^*J2H(tJ@Fk!)0D;j5Cgr<=X@c}G>^EHmPs#Bbyil^`U4#(?| zi`7sITSZ_Qb{TEZgBDdwgX=Waldbd?FkL$Grs49oQl?%fRpihm;t-`TRsOglbTXs% zG*IfDvMO%@=vY3*___oV4vhJEP_4^DfIY~T?Cd@%6N5PEfUxNNyRUN~?BNx3EzZyf zav^VSiDe$@ASrxFlSMUWroYb9`mydLV43*0D!ytwyk%0N7=UtE#)G<|8G9(t$d%WF$Y^d;arnBH4X)dhC6 z90d|F+a(A*!}L5{*lm4o)q9Dy^K!U8@40tX1Vs`YiIY09{GxC*ScI*}DH{iuApb>Z^3NoW1f=+CXwJ|0lsOt!+*v+$1Qdn0n0zyIU> zYkk@0%+geoz;(g5j6qjGkA1T;Rgn9&YcBDUUB-)QLyw2BTK)t=iD@7sTy3&o`_lEg z7d2)l02>)VSww~!*sxBxO#zEDG!;IIN(h(bGc!$mSt48ln?Rv2chsqs%?4W?8f;JO z-I5G&H1yyxf;&>FQ&GmDa{1K%sh^zJ`EP}pUb@23%4%>V1MbH%N{8k`M%?)w{($A~gStv=(W>^MwS-|c>$5>>Df|0Lf)Dd9F>}{F zFcB>rAWI3=-`0r_jpxFa5LF)(qJ<`IA8K=(XuTMDQ&Z-V4< z3-3T%Dsb8kruhSpVdlt{mr>7(gJ3j~onc31Qh9?@h|4WwA$>om(ZaXUB)X+^{nhEm zPk=A}NkJ-IfAZ!7?$nY2L^uy4zod?$1??Z!a^((`=(a_=bLmRMI|N_Zbr}wqsD&{f z1Nj1OS`jJ2(|EVULrK|hv;9SQM>L z4+*}fd894*oJQ;>eQ!6xmKwU?x??2m5$m9F4>6TRwKKG&xZ zi*3z)3XgYd13A#ZimQk{!To}p{&e0l@cj2ups=gK{TRBl_$gf5Q$TOD8SASWeH4m% zi+p!c0w_KqW|+q4I*gHWw0_zK>$O|*3Cbu|lNQ=EtDL&;Ljv?B#b(o%M!ini^{k4L zI0n~I0^KcIVsPF0xJWY@_g9wvf-DT6gQZP2s#lNbQ&@*_Tf+HyJ}-fxWA=e-z}&}2 zwR)=o<{vzTpkR3yv%^WSI(v&qVjlkU%;&xvMOOf>uBfb94)U62%D(H3rsk}v6;h7FCn7Gw=|Om6 ziX0S9^-eRPgOIR-zlp~4u-%icdBkwk*yaLYtbwI&=V-@IG-E%2O1@IBa2O#zKQd@! z($n<4!o&to86WgeEo5eSw&%)1vEtZpjts@b(#93_smMeZj*vIzF5UeR4;^GX*P7LK zjNHnVh{K_##>Jppm5+_SP6&t9%ek@%5U6#Sd`7HkZSfYAXABK?=-H5Fzo^AIvd zASgo-`Ge#Ldd&*?+_cMze0D|wl_+k)!69M7P+ejPaw4Kzk|rcai;rMuVRbj3clIG+ zmRjkFNgi?FbDymgkvcO|LaAS$NHMNAU9-5DR1gl(mY}Af>kIsm7TtjTlkJGRFjFX- z9kY?zXUL_!4*IaY7^IV0UKsDf_c?^|n|`ELdcBS@(`Z&mbdW6~tQ4V5lQ+<+JPj#_ zctLK_HLuSW(5}#0+lgFuLm!8Y6d()7&e7D4*A9!*Xo0w*1}0+v1;AP^{vfd^;k5X} z>OrNhje2OAW1ExRw>8cV8py8n97Y_~dRzxI#83T{l8#~$O1&-jvmN3-Uf?YmmQ16d zIi2|NR_$|XTlg;=dpOkZpZGOpIK}3?|KvDc8onp5(;g@%F*{{j$w46=sm<&)`tttz zt`vT&s;DCb4AWAFmzsMYBcs4RkaCOXADCUu7$yt#WW9)Eb&}EqbY!NIx)x@n-YY-~E1LaF zW3exYF|8c+*TTzHLboX=OD2l$)Dg{MR7D)ZYRCmNN{>-5hmG&F6xDhZ^Cc@S`xj)s zN0~W^Wt0bdOSLZ}Zwx*2&Z*y)Mc!G@`C1mAN`=y^OFhW4Yy@CHhS*?X; zN|F})tg*b(uJfW;Hb39-ZJ(aMzxe`hAMD=i0VOY9-KXn5E>uIzAqp|1J@=WfyW98R zpP8J`0JHs`pR)L28VlFH(?y}rxYN82#`pXW?Mrmar}pkHih?(**pLsR*=^-Gx$K-wtBT+C$B7kHEj@P` z#e&F!KH*75h(z@Pzl3PT;iV6yGgSL+k^r)>$+j5XF<58@4rUNo${Y>Ze=gniozkZ7 zLN;Z-aqiLh4}}dKXne^7V21~6uNX-_y^^qDIXdd@ZhnWz9%p|M5eaAlYgBqVU#gHy zckyD*>I!}O`^%G=q>2}lfnqOd*et)NT}*_Gg^~r5*IwSnaQ}YsvI>w3V_a$_#knI? zRcEyu!sWm>(=A$aKXvIal7+gbuP|5D;ESevFydyWZw+s39$MV8Cbs$$higwe1XYP* znvR%>*4g}u4=b&(c*peGfTvE8bIkLqh@nn}s?~*6OI>!`+{q89beX>yjgS%oTc5*|ac{<^W=6O(jGr(7xp` z+!^L4Asxa9n2I2x>aenmB}Za_ZyvliBQeXI$v)FgnVo-SjX=)O|R z5<{e&d7hp9#znsS5sfRNXTS4FQc?=EF$r@Ny&nywzWW$1{1_$3B=yL>LAJSJP*ygULD&5CS;!4gvEg1s^;vW? z#Fs`eK$AoTC&>O3jddkmQP4_21(rJ95*t$(ewcC7M)8kPxpc`OKPMzE7$yK5b$))} z2V03h>?yH9;1nky6aja83vBQBinpvk^6s0Ij}MtG%P;{Dcr_aYZv4myk_#Jm5{y@r z;QB23cXbZGc5`#G|8wi_JoX{TKj7k|dt`^!`Ay7eh-?Z(u7{mJ~G zqFoZq`g2@lf#)%`nb&_tg>aO6`&o>{+z3^Qn{>Z1VVm1l<_|kL{D9eB>Un`E)fsa* z#2wj(43#)R1xvN*+xW{?%%vo$F({tbR0LN_u_pYPcpn!VW53$FBxMA|!Y~@?c?Axy zTWJ*84bZgSM}?{^rp}je{{AJ7i&?yJCBk#g42?HUSymi}321R(4PYXKa(_@xG!#$~^rN^F)iRe#Pj9Qqh!a9|aLGjb1(zA!D4Q4W4vdktU%L0< z6l`*)fO0%Cq?q@fuc;Ma@x#?*t0z!eDjWR0Q>#zb60yse!TY;R|H8fZI-m^GSutBO zD){X1E0B)^3M;gptlTn02RcAx96;Ht!iOFblVDzbJ)8UptMfhl;Mt5(wwMuztrwmB zW}idT=5Sr3D|{8bklGTOo*)BunU0z??6Bfnw`85nH+cfiY#y=#h{cg`eBN*k()vuO zYfzqDp)vR zc7kTN03cFr=dpcde`kL~g!N=>s#L+X-pGVg@Hez@#jDdgGS?!nS|tC>jA>$Z>~bT_ zKlEDAZm1GVi0JZz&CLk~j_c!z^cY;GLd$w?>GM5Thvd67*U7sr!2L8cc>YmC?v)uaJ%+3tMidcJqsNZ1p_VKUmBi&RB#r6t8Cf0ao?bUEC~n z2oLdcsVKMSVoO8dX)C+(yTDr41MZB|yLay>!zNZmSSA^hT?MswH|DpA!<@SdtoSSY zSFg-vSVa;OWrT8yeWwY8M=YX8+2LIDp0k?uwud1*eLE5xM3|xvB^Ay~C;DR>u8qtB z2mO^48_;fpvTFl|_tWALGW>1JF{CzvakZ|BeayBahN}aS-}*K0J>J(yeRi*&>|X1` zXt-qicd1)F&vNWaSI~Qw^#t0QI$QWjT$&iOvtq=3euL`QHBY&yb6*m7`!j2w%owZ) zr+~36N&$tVF{igFyY`V<2q;M&H%g)pBR&OaeZJ{F1DZK>&o*T6y{HPRyC?V<1%LrE z+z4bK9V5-l5)kwYM5&)ql?tBvz$ViX%S+c}Qm-482F*pv+*0tpJpbUqVW*HZMhaEF^$(mu3XPCa!RrvI36W(8VfH=w4HB+!HMJDM zn3sLl*%I7#Zs+ekxKW(B>ZJw?d`an4T&Z=Uurj4Vq^*F6R=gC++pO&Bd<$8@6VGX% zyc`+GEL))Th z#OHlhCTd(Wh2+imNb6@>dobNL6bX@WAwd&EUcM7|Mj*>{JX*XGnKNWIdIC7*No=XE zx~{O38qbuO0dm5#U{}yL@6y?$q74%p!&2L^|3}kVMzz&;-MTn|Lh(S0yHl*V6e;dn z916wV9n#?L6n6*|EAGXu6n7`M7ANRQpZ9$0U&hGZ$&ZYEWzMzkxm?}A6_`7d?i<-z zUZTuxO6CG2RLtit3dA3hmlG}?u`9_yg}>2JT%;rl*kM^KWwNiEbrhrN#%nsnHN>aC zIoY9vzc?zQn)&Qu@-s5?U=* zvJ$<$hbFNPpZqB4wcR}wOmz4p3qt;qgS|2~aJ7{q9J}o|KZT$nuAz~|rgSwZBR*|7-;@;0`04QUpS7RXJkv5ykq)9l{Pac!q zETEQ0^pW!;D`kk@*Xyi^`Hnn9wTMiFNw%;D{4h_)eXRrb6j=Rxj!&zGJ&lfUv-sJ~ zw!$-QMgIIrm*2nH9c67`*TP{L{izoIwlFd>_mZl=QvQ(7=u+_-5gDXgu|xdUtYUKR zzKhI~m2rsyhpr?wRKdO%K626LR5A2v{2?DtadM1(roB0{mejK7YY$GaD;A5%*Ki>= zYF&XCrPxM;^M3U52~X9p!pH`{`WdHjSrbAj8(FBH;QaJF z^?oa-jIb-54W*g(H*?Vf*u?(&mkpJB&#C;P!P#&rNr}AZ*Pm$b>DJIj+^EO#53(`0 z8|g$H*8X%uGcLFO-vx=TL z$T7o9kdKu0wdU{*_D%J!zj|R?e%6yWCS_gppvHHC_33&B?dEAaH~qt<-l?gGdSYY) zWr(}!Bi~-#Gm~cpneeRYt@eNX-H+qxoZnhFv?zdLZ}u|<`gHm7KHH(Ism<>`7oIR4 zkROsV9(N7vx#oz4=*YRj>GKaj3S(%c&q_$C?mrLV(yM_ZYfbFtajp=W=>Qi?aQcjn zKKLmko^Yc1KjG*94|~SC0|mmlbNwm*DY3+MZHje~|24%*+kHvb>S30GjrVJwUEI%0 zjxW9MHttQA+rs!7ZT~X~`DQAX&-`zNpyP#XaH-aHr>Nx(^LcwO=m-U7@s;thh{*)3 zn4gB73|P{`pMvvdUbcqMZaJr&99{}n!VG~U0=3hbe?N;yHfzSSQj_Fo;Y&t^o8vMu zXGqsmCQ3Ji%i_*5OGq05@;r#du>>qBsMxc1CdR1`a|y*sLZglxpKsOPDX<{$A=i3gO+NZ#q5R9$ z`GWmT)7zxdF{9Mp%Y1f)8=QSUm9x>CB;!c}!HO0jR;Hke5Lgzw3R10^Bsj+TC(iL? zZneAN?4YV@pMzrB(2zzh`~l$uHm=H$0>f8CuB^E9`eg;NXdk!cT6p- z2pjaE&NwZ5yPY_3O@MjP9Y>VPN#no1owkyA^+(R7z(4GU%yb#Q>76EMXd?JRK3w>W z)X4f5bkhpN*E@E}qk zzwZNZ@4dJXXTvngN-OR2Glpozvp38K;zP1GI88N7nS&2>hg^$UKYfpBouOYvv<|o9 z5WJZulXOvx7V{JR+dCbaoLmKLRn9ndS&R9~W=~|&756)*jD1`2((I>(BM^jDPH{;`{W??w(CWd!ryJH-+t%WD!E@@ zJr`KjG_sSFa}qLfmT}Az=prGBh&98k%XGq}tc1rGuN*Otw8W&%b*8IU z_x*{2dfK@lXB;MK-xF#?aJ=AFf9eDSPl*R>00JOhMJDxu{$$_@-Z!Mmm^cZ&GDjOO z6X-Sbvgc*KLULYE9aL-)QO(I!J&9OGD3Hv_+#t>5Ngu@52KI>J-U^wmYrHQx2YU~& zxr(x>A0iT8`bjR(w?>g!ClRyb_0r?Q4~3iL?@F+JPsDT|_WGk_r+{$jYIX%ne%lX2 zTlbSw*Zta?yNI&C_e|X0g;31@`wzFnd7{@p9@52FD!Odszkyf0kDu!brw|U$~vbZ&p zeIL_Kie=qiaQp9VPAGdBN)PekJ^6EcO}iMLS%Gp(gVHut50D9A-an?7u;5#GzZ&$t zUUnN-jAYYdE^R0pP-D5Ad=Gl(XQ!Zv`Szp^u?%eUQ6aPuq*Txm;mz+3gWaO%lDt1W zg4%SeIlJa({Tv@(4`eDB@SeoS_1C>Cij{|v_{c{1~3Jtv8?X3SF(8k_~`dUI{&DYX=WRdM z%T~vrSe(bdo65m}X93oob$13G_tVQK%pmy3wQqHN8NYRCG+t@{|9!8^>UH0%5TWq=SBDEbR&?kluMn*}amOz1kk}sb|yj^?|xTsr-Nhj$m z#T5O*mgsxGP;ZG#XKcvT87!S$KyofV!SF@Xo?*Y9E4rRkqVe0nYo{L8M+ z(!X)Y<>YJGeoJNGn3BxgfX=IP0l_H=xi!9d93BgGbihvD0#jOD(}O}&@0$-&+N}Dd z6n-4jKn>~bf8pO%EDPZ^kOa>5rLoSwF3_ml=wI2R*0smeEyr##@Zo6YVd}@M-mm;iUob@xcr@-!s?0{G9fC;UdU_iD@a_Cr#wjUU z&Q}@wn_nQ*%$4f(^4B#f>D97n*=yORRkaG$-C}^Tb(j+7sU@JsRRUOR@v*R=e|`IE zvn7S3`cn(VWM^?y>$h-TrV9QKgj-20wD02feBtMx4Y}aW${1%KQ4MAM%>tR*{NkVT z4ueBDrV-)aQ1vjfk)m+b(WdZZjT`npsR8q$Q zwEj@QlMXxa%Q2lg(h?o3B@dGunN5OAdTq>$s13Z>a#L+6I|-t9bO*7rvTq;cosubg((~q5ks;TIYA%-Pi3uC6ZYB^&+56X*=bN?H52zctdws8w1+9<#9i`P_(C z-=IU#YMJ)lky0qDSc`jb0EJhY7gUi@;f3ows+69(WcC(oWK*{9JU(AX3VG2DTrIZg z4N>+x(?(2g!8k%GRMceFVi>ePi(5}{|!d5CHuK*3TRU!YME za;_PF*f)lH;sZAqzXK)GUQxN#&L&&XIy`v%d5dRZw`N8HJcRhHh{6+|DZxP&Hv3H! zHnPdn=Tnui>-gvlZLxI0q*R6OyA8#dtE4D!YJ4?qZmad07hrtn*w10#f%QT-r>z;n(<{s{H z%B>rU$mZ=}miWj>t!}VQb?usvYBTd(qK-4RS6>L)7eJA-Q9z${-73|@ZJ>{KnRDoC zI3NmizTYERJ(+&CU2iA93HFM0bulaVUJ&VPpFPZHb^j%{t~91-o8wa>V2ho&&lF9&id@tMBp&6P?OagGuG z4Z`bMNmK78F98y|Yw$^En$NJ<^Cb5aPB=zpjFWS|aI3l*-i?q&I0ziHBOx%hJ>ByH z>#fi+E%VUE;X$WD@1?YR@aQ;8W|!EfDdwpy)9(FKU>FU`>6bd7{&^BEiH5nYa*B&v z$Ei~tx|0gpZ87OzDP02RzkZ94r?oOZ>}V+faD^}Owo!OSqGdck0lP)y;p#{4>|k9# z%jQ^e^jBo2wVLA}5VcqAc=hc9BEGrLrxgXLbbS9V*4$k}!j0tGS_yWgMfLL4p9i+vUDu!hZG=0B&6fDo=ql~O-rzi!UBbsS2ack(GK0< z5y(^^069%6H96d%xh1)b1Tsp+qJ7C>_O9A4uIE`S-WUa$y%w@?T}&`)r^O&u7<{>x z>FV(`Hb_t!4+j4Ue6-rgUGvWjba_w;xZUBqyM)FXfa4rD9Mt`otaA6sPvjg8aVTWA z38PFnLvry^2%*7>=? z-%f0M$-e+f5pk#ZX~u14#DeV}cAf}KgiVoqAvH&n_F*r9#~pHUY;ry(o}J^rSDvtO z&j+%YD|BfylQU4{_fcCLCP0|>wBk$X6UssePiXgnvbNTc5M%_ri66{ZSVST6wUGQp z6W9Ii33Kfo;SQ=2p_a_WTWeE3qfS2<2CF(-XPQ<(P*nIH$5!ZS^ZY6s_2YsZzI#>; z1gA}$B&OHhVyU|skPNYmmlFP*R|_y%LC;(3Y$Ri8nf}JI^67Bzr1pQ#^};UOE^4b?5VL0Xm(n13ZqDD6wbUw7|dQqJ*r#!`+~`kXerQ zp1%Vuua9!-G^mhrbA{f0E+}Pj3op_^D?d$VABWTW=c>sET;=;cW>snlgDP1|%Q7Dp zYabM?$5%Uk-%4aX10$pm>KH&2vqL)ikHaLhzmP=VE?w_aOT4bETJr3Zp7(gPNoLZh z3+{GNwJDCsEVlx3V$`1Lr|Wn4kAB-|P%nv4$LPmW!978okyupPe(F2j6qw%8V$q0f zvT;!Dso%R8xx4Jj^1AKq;RxV%^58Fx#((OlqerBfslXKr8t9fJ#-T39Jqgtg#X`U` zZ0o-fEEexv;S^~uFpBfyovI+i!~clqF2*I|qqurJ^u>cEr!wQS`}Bm8QODeB1I16(~wqAculs)8dC~78bgo}!9|tg%UF4anGD;I*^o>0uQLbyoj8oh%BQqM zA|@%a`ALA7e68d*M3G8V8)|tqaCK^1~Wjw>)$;x`<;$Xy-8E2b>2KlL^CxFo8j}(flAc#06F7z zR6E~qyY7)*yjs~4dg^sX8nLu9lUHI#0MgnNDJu<>^OAY=WH#Cc<_H$zi_0B-BNe-MBx&C zg_n`fn)d@6Qs?beqgjvGgH=`VpWnahf3D?<8i}>Rj5{uG^u+=YdSRz^?*jgIKMKWs z|Neczm1r@jW@qQ% zPtm?-rGyQic;&b90Ir5nj`)BbO=gUQeNum+A%|;KJ!zTuWi-agV%Mdtfuc&J$_}?p zDm*0|qWQ`d?h4Y4GwPzryr&p!27ry(BGN{diW2ooWGss%hx-#tF})R^r$42ox6qPd zJ-R5bn9dAsXxBqEk#l5cIX!1>`$J4c)a`lzopElL_9#Ky?DtzshQ4LVvNTaELlx%* zxdAF!o(~M+^n+mYJARwaD!e%bv-K|@sMRJcWCYf^b8-uxB25g#pD;d2`WD~k)I>h6 z!C3tEPE#G-)6xZ^s^s#PJ6wGVSbv%_W+ZQ#cc2x)0~&x*bKK(}kwBEhSv+Rj7}+tl;b zK|PC%CC{wViT>-%R-cKInPQ|2!>XKOZmh1gnKdu^Qf5$!wWgZ1q-HjBKWT$Th)cH#u_+8PCFW&acJU zTLATKfRUl*Fqg80PI0x1>)_244L9Cjm2@x{mFFwG%7}$(bn9R@k!FyNLB`7Q1JVy< zIT3ePCFKNuQJF9@o{iM!dpn^m+*QF(lElx}(? z&JsQJYHR}f(4=Kbkc}Ov=98Np*IIJ5?uv-CW^=&y4+kb~aSbzmx$w6S*_ZphEOV9# z6CAN2;#7UuF}P}y>MC7EoQ5K()`VSLr;|ytp0@-iW-PPh7^Bi*8F^Fq-*5{itA$<< z6`GNvD2ttrH*6J~(C}W{#-2>j8|ZX1)aXtSPl!@N3hgkBvRf%2VYsM;zB@&LVmhc1 zzn{-XVM9}mVx#D+P8gfEXL1ao%l!FgrDF<%1isKKGOC;HK^;=jfWE7{_83RR*&y)3 zVf47bj#YTx#B~BO{#Hr`cL{=$2y}2>HnOjdZpQ`8X#xw1OPRQ}&ux&`9XvhmYnw4ZhJ0e0Yap^5w>9$yQei zdYX8Uq;xP<4(2Dg^jA5?MawK{?4s+l@imlZu>Ua)T+8xUo$Lm-QmHX(3TeMzh0xJ- zpJ%*h(H$#exPYOi+PbY$SR94#1J#?|Bgls`ku19C+>szE;h07lSH`92KPg#-E_M-u z#j~?q_%}4{zqq5t5bzOsQnyy8$AAqW^ty_JOIP9;2*n(5ZOHkht=aK8XS&Y09)lE`CXEB(PZd*L<9R=}>0Pcl>(PtnCQ-fBmpN#&u2KPR zAF1oPM@b%OR9^lOH$vbQ>NZiH*(nj2h8CfNiTeiYB~_uXtf8Z5C?AS^`RMO8Tb261vvj9$O)HH|FG^4Spru z8mNUR5)1p<={Vk=-9HXz%fG57eAydpB017Y-Mt$L!Gc33_zdCY?f|Rn>De#&=rtHA+-@jkk zxoo`LZ?i-l2Vg&50^euBzho}LT7X;6UR(8Jz`={x-bvFR<36vi&tsf$26BwEJg*p_ z8(B%`=c*#6uu4dmxe$m6MCQuCxG@u@uXO3B5H%A#)Y`)9@8Lf|rDsToqp^Y3df!BK zve;%dfj9!ZpW@6?BJOG|W&63Z2FKx9EUv-xHi*UNF@s$d8(J_|uFdcx)nI`2VUVI! z-*N3}`#5E%#NU6?TE3&CwRbuK2Zzi~|M}WB^UbZr!=lWsU4}BQ-0I;EAGX$)?aK+Q z)r~0Gjs-hj`siK~OKH06cq|)AcZI{fcasDWhAQ7b8DMs2g4J&D-SzX1<(hypw(3mF zBD9h!zLESdC&qqBFWZFBvD3uE0hi+RcWp>N=0`d|2+frz`4nny20ok{KGzw;lFO9Y z*9h2(BeIv)-XJuS1CHn#kZsuA7*d>p8F$1XWqBW^S;gJUffxNme7xh@5tCA&mKHDG z27?-d)ogqfHV1@%i(B37^13@#Ex8-K6OoQHvVOl0`mBYO#N`u6+ ziriyqt@{}}-80EuM zlvCsl;HgB+W$5gYX)74PO2XYYG}9l^ITKqE+OmjC6}HG|QiI*9du=Kv4hv{9_((>@ zi4-oZ?AoN7d0ZfF{uQ0&sDDn;%2CwO7;d%yIt|`H(e4%jYtrOSB5ytit@9iD~>Qa$|7}rDtZ; zH7WaA@iCfJ+frH2WdDk9m`vHhj2?_&(_qg8pXgRYG2w~oIs05qhMP|#gvPYkB=`Af zC+AarMP`Wp!XtU|x<7`}_GVnf)8tz_q}0V%Wue&Pd7OxZ)!0UIlE_*YYYX;S)RFx` zN=m;Q4Hz>;AZ>=cH#oH6UTwMk;)@Pc{648Q!)0k`hno}F!n2d?5|;a1AFF1bh;)dJ zM2hWhlF`sotJ~!*)1rZ)D}qQ_PyMk6o1uc*TV|BT2He@k8l||ng}%__(>W%OlNrhG zy5Q3#z~;fUaPDQv3599Q9vUS`Hd{F(M5cA$~?c+RI<9PGOF?=ITcIEw0kKg5l z?HdAxR0-ovU<;d{LI~q1`xCQ4C9(npb{dOk%bSwzfDw2X7*+kV85g`wcARMkF|23~ zEtA!M2x3Mpj<|Fdh*yxl?`vM1&Se+RTi;$Z! z5pu=K-asVuw0+X)U$)k705odn6PMs9iqkl;8kbY&YblKuy!XE$#^I5+Au*INUQyF> zmm418+0v%NKH_p9S3u`9303)&&FoxTVAlxV2@jodYo;;_lf+*}-~*1QWJHm!1s-?L z3ptH6lknKY=k02v7_5%1XyGKNV`j?>d1!EwLO@dJ{$ct;jneM&_7C}545UD8E2^QO zIF!lG;r1{<1Pv!x8>!=S45IaIgTV&@kNJ^&^&-GClgTH2Khy7wr&f`D7HC^DC*-w3 zKt~C0bkcGz%0A^XZ8?l{8?!_Yg9OS6_*BemB=?a8hc_*FKuqCJHYmRBp4Pn1&gXiz zxQj~VO!bj}`PFXG{6?-sIkRZ1C>&aDz(~`&-5Bl#TDnS;Gn4C`(rbKF#`J^G9;D_r z%#Bor-&i<5hz5zLo%SU2_-B8>Lp2?rS8st$#$=Lw^-xsoDi{1Vw}ecMc-z;Zzg(_& zWePxLBn}=~o}yF}zeg_ccQbl)7$B%KNS(0#r(sW>++iTaa?b{(49OKgS^)JoX6h}a zGdmW+dRSGHw8l!u=MI^c43Dft2FcVylBL}l`}|Z6=+HIcmCysPi=*KeiuFE%r*<*F>;DsQH>2yY zn6t~|dLzZV?6}jv6k}8OzkiSOz8n_{o#<_HTy}gp_k-haw|eaHp*YvD^C#`YZ-wr< zt-U(DGKAS&4Mf6jDaJ~~d#P7r)Lg4G;?m}=i?LR?ldJ{OQq0s1vtqO08%JDwvweK1 zM!O;F%kTcZg6C=UyjN_qbM!10dTbqTPh)|z$NppP&NM+IwYi$5PX%*KrXfBH1^$5@ z50BqApW&z69;IHPD5_84NJM{~I^jcqAKMDMj0-zb5%VjIeOO)^%)g2|Q@Xk1!9E&h z5U_i>aP<_sy7y_(nA!n!H_Q%@#+igcM6i}RCyN!mzSs21t{o5Q2-)T0Vx;yiJ&cn`LE|k_f^gej^nvNza1%lY|OegU}k(sDJdONmld5X0~ zg=+Iwq%iakLS0qRK`|&wk&r~skPMcuv6A>U{U2GZb#aC3r=a{>T7Tg}$)SP!_HgDT zJZ5)0I_22tr#Cqy4Cy-lJh4_ULsskPTuZHNc0(6UIDJEILQthp7R1pm_1cdY&_no zjr1|FFCfnt>nbYtJu827==V+He&*u0Z}o~NhkYefR zH3KVZ>#`+l;3ih<^m2Geqsr$aO|iHdBg$?$fAJZon2DzKqX+){{9ccmr#h7hVv`_B zGUjteop;yoxr_`{2Sjk3sZ$w*br=T|OE41gymJ!>02OrSZqmXBHP^33rLcHv7rPDj zrvSlje%Vd)KFi}?E<}X+a?9{F1yoE^GVqRR3wc~Vn|kY_ul}ozW3bN=xj$ajXB?Gr z8)Ef`Ry0rC{=q5pPCXP`=CaShHeL|jN?lG?pbb+{Fe7vRtPUL|6D}}fGqWlDXvev| zd!)HE*0-GG136-I1UT|bv!W>B#ZKt?CY`&h6==JXaQZs*3tj_Rmv6tkb(Dl`jo@x% z*>WRk-?TRGiB#`4T~vyM$Z?;Ihc!Mjd?^iKlXZ_mu@DLI98x~8CNeWfYHOlUO)h(* zc#Aom>1FYoPIU$)c^PY$X;TKH8W8fijyKy!DlOZV9KdNweQJ_=FGLaQuuy&&4ofB~ebaVbiHkM3gYOXV z%GtnK&rU2dg4z!ZM8HXAYH8_mal+ZD=StYuZo**da*`Cecn~Sj7M@z@?RPntob+}#luiES3wqhLMWee^^-rq?_TkakW!UdOB&ZB<{@t zN{rP%%W;=(hc9>a@3-4rU$wpeT|FPW9`G!1;v2XOO@}iLCV2j5+401RdLN&CVCXC` z;2!je2aZgxn&IG=ha`Qtnv2%n_EYnd?!4>1v@QMzJefx@^cSlw+$4RBfdK|nV7Cfl zNWbYO($MxsCkre&uBwFTf-aKe^Vma&q*#22D5K(+m+6Bdtv(jXR(#Wrk2ImApF&oV zQq+4p+C`kz{ERi4JFbqstX?r%Z_IA1)GUjnu<)Jjz`kQ>yM6WvK4JZM~>bPfnczMP{r%vf5XI8c^Ct|yra%mTDLp|Rc$oL z9gth|BwmABBvpl_E=*Mfh)+>Zkwqeb`4Q?{fMK*&WdQ>rDmOMF&o4-GOXOYOX5}kP zNWKzQEFO7qOf_(2J*fGVhXO-XYYkKh4Kh~>7y#_I3x%LCv$xdgRBC-I?IJ#`Mdsf6 zk^%LF27Kp@k@$X;@N}?6K$TJvE-tM!EwZb#v@{OlBCBE(xoj@I=h5>1m5Iiw^fzmM zn=v&5sny#OsE5k2FAp-$$9cMvqgp`e63xd5!=4eT!(?kmC6D^TViBcE<&34la>k-q zn-sqmno6LoEV#2!NGOCS`071|H75^eS*i!c$GGt%>W5fsUpY@lx!e0l4BA3~@)uJ- zFXg~9Y-p*@@gLNyjUQjS5xKV+|8Ewc9SK0{krIGY!1Im060uevCr#ubo3k|m2oagz zRb>vlv`uAP=^BGavs~Ns$$XS7FlwTPD1EOHjm)O5oN9KT01q#e*Bk{|h3!OhHVSUN z-$>PeujJL)#!d9RnJM(V@%TFJrq#&v&+HDJw|}P30uA}!!@eXG=qzCsew&>l8Uw1V zKea`^tc-x2Y&FO58!rB2YE4`T)mAMP@@$tOw0VIS} zzoAy$6YWRrgwED`oYq)kD(kPccoIQbG`q1nlKlxLuPu>gv!AMdc6mgDEqm>H6!K4R z7j}l6F5Yetkz!rPv*aU7(6IuE@oDL>kQ_pH{H{<40l~8nb;n#&bnmXswZOl(`NY%S zrq{cC6ANEF@*+2;`<^*OOLL4}USgIfIAD)5xlqYp@^q|lxtci9Fkh4sIS*m;$I0pP z=&wQ7H00hzELI)F<@?A}&*g*>{z<}M!1g? z{iZ5m;c%iXz9;e2EymYsFAQ3XO<1omTbo&j(s>Jk#>COu{LKIs)bjh(oKGmA(?{a0 z$VF;;zKbHNwxY;XU1riVEr&(4V@mAnwS1EL?2<6jN&TR__2r>Z}2RzzxC%yhk&GZ<7>*NSinzg5vhd_rT}?6e=zQzV-~dh)XlEwjn=0NfOgaViu&nM=lRkr3I}b41HtKX*~z+7NmA`kXnQH381f*E;Jn ze#P*@uDTE|=9;~32MY}ia{|vHhhs#~Qwxu}hpCN63YbBd_Ir40VLpoAnX68>*x3jF zG$Yb)4MLlzOJ-w*R3dZzV7BBslU7Zoz<_hhHPKO4@c%(d^YOe_gZ#A3l5adPFAH{b zVYngI1q%~+{M#$^2tP|&2jnmMPhzD-i=nQebo$qA8V9WHQr!|wtK9!{{os|B6ZZir z(4*7GF%dY`B5PJAWRuAc+<$T^S`^Uu69jN{I|C(+m@V?%W42PL8_siFR9W@4(s5}*8 z&V`g%a+BIAWE28bG$D2GCPEF%oz06rSNOSXzep>r}}!H zF;KMk=A5DJU_^VGovmMLCBrM>jXPUtdE*udbNak$NiSl>jP>~QW0K3mSRKXs%gw#3ydFyY0bpUt;(=lFJZx z9I+20Aeku+PYvG|5x%+&iNVmMcz?9-b`}3 z`*ju|Z7$wkpYb^f&00Onm*pttyU);qW{rU!ObLA2fZtQ8)o*S?I7#}0fTs_SNFj+B z(tzA@uJu4@?Jv(bcHbFP&0?-L&`h-s{Xg4e9M9L0#IUfm@F` z2bI?-(UuW&z)&;O+cxdLm}`CbYFhSQ5)=oi^5}$Wh0(t9<@YJ`w#TD;Ti)XISeBKqxHU0y3E(q(85APsZc3m z)SmLe;K#eS2qRz3^aXDoB2%JUTo=T@Gb_Eag?0C1C>tL%UoL@skA|%ATBT{}yWfzk zT1f0K1~ghc9wSCn7BLl6GV_t4N0IYvR+XXZA#yfme68Ot3JcQjZ)h zcNeFy2Y1~r#ZIGu%fRUVAe}js>>F9U5mT8phs=1$r?peYjD;Pkz$yF(*~m)sVcKnq zn4+q|68X8l!m+-c0NNXoD1DLB9VZ*9{~>Ta5B|h`{$qGwC*)>% z8y-dXRAJe7Ely1Rk;Px6=9uN%*}+3(7~8|>?a+hkiU}!8MVkl&KQ!g1?#C{i)|A3S zC6AefPL2i>Z|buTn%F~lv>!2orR@@?MVSm4;P#yqh+oDwf}fE-`03Arf%$-lk`GI9 z3guveUuUs#XQT%v4$A0)ZqMB!&FvOC2IA8qn}i;`*)|1gHo#58bXZsTv8Idbn43Ux z#{YoUg-CMIi*&G^EU2vX);$CfHc8%9)_xJ=do_yE>(hUK%EWg>2CfU9xV7TTW0Lq_ z_hU${{K3pSh-2TZEhIoZRe=`e&{Sd39{uev7CbP&n-hBSs0e#yb9pZwpwbUwP3h5l zPEZ<8nS%vpZvdNc(n=K_5mOld40H=gk=Vy;6-KT6_6w($J$@8SFB2=jIDz$J3*=6! zYrR#3nRSyO{iM^)Gx)~ zQ(l(pea5cJO*m>kSsei4$Z6vG+lG6{7iYV9s5>Tle%myY{%{j+EP||F*+=2IRcG-- zDrC#XSnThAqH+Enf*OrQ3YN%IzUCV|!{@rgxQlA8AUmA>r`* z`Qgv8cdgoWgoqyLdU6X`1VvFrqEqg{1T>sJ*JZLAO8&VUyVT$+rFrL92B2t`Af}hcPcJ+qWJnC%jhd z1zT?=H}@A^v!KY?7j+eLD?ef{gmVbR1p@5YYG8Mq^SPau5wjONFsSQp{Wt_fP3^&2 zqVrKtgbWg{sl^md#Q&#q^0f+)p|$HpruzP+e4Y~am>=hSU?Z~6<;33l9lSC1ui9t) zUIuS-o4ixSEuUK-HI^Rl0579)#_-+h|MAM3#2en7BE4f!adh3t?c|#mxBREVI@kQp zWX7KsEuUL_{sR#7Vcg-)IM6TmQ47HiPNY5XS?A@&SY_}0eC+GNgyXU1xa98Dcm+?J`X{xxfLr%xWgEdt><;Co*6?o}49TPPv z#|KAXAw`p=HLz4itvpzwT+B%$UE3&3*!EIe7_4xz}Ffc-vXQXi6j_BGe;^yz>cI{TUKv?Hhn8 zOc`kyHc5V1+$Sq2GFIW(A$q;8>uJ$?c)62$evk2v8!zQK#l2|2aMia8iVjGd*iK~V z)1HxBIdP&qt4?62=FCIb%0|)76gCz3(%+10$it-3Wrk>0+BYNhj)4aOmlzv=)zn5p z9ox z73{{E+?RcIiypr36ffa48;-@Rk1&A z0U-%@cFUJ{&ZwhBCXAnSv1Fa5M5(lD{RadrvQm#-X+6kl@h^0jFEy~Oav@EEektNC zFdqd$!^!OIsnrf?&m*v#Z_EwA$*paZme656rv3hew>rSJzvCge%@bVbOLp-3x97I= zR+6VDX%%1cQ;r_9HcEA{!{Q_d!67)t_rg@N0p2n#n&_9%VMrYnpJ(9|G^4qGWf855 zwK63C_VvM>T{X)*5dXn;kdAk23Kx4m-dN2vn~X7?nGhG(6CFq}>)p1Qrf) zOjF)_@}T@kez#f)aKbBtd9Cyfw?%BaO_HC<(X#ru@lLFNrh+(9+fXDBP%+O)w5%jL zR8F$M#hU z_i|prjGFc!^%M~F_*llvhrsh{Etbt9kdhVre64Y4D!Fzho>kR_M56qX%?CNpXkU(> ztMCwYFSV-%jD{oA89PAQ{Ds#0JWi!3+4VoKNRvc0j(9~|MeAzW)M_J(&FOXU2QZ#= z%Y@A2cw&KQrHOD2r6AXN(=hLJ^4uf0&U}ZTY8tZ>EmoQwD1#zdtnF={nFOfHI%KuR zKZOrC@n)C(X!W~)Bo1Qj)Z{CpUF?DmQ2<7(%to~)=bTl({B89HP?LTug((07giiTN zwlBRtq*>Qb-+6s*dEOsPGcXjs1LWRMkL0ln(|wCfFVmdJ^md0$DP`V8@K6yjUi|Jq zRyjAXO)GWa!`q*RW=K!`2Ozj)N>phQd0EZvI6vOK4gP;Lonv?&-PiV;G`7>&b{gBZ z+1R$NE4FQ`v2DAtlg75*tM~tT_s5xI@0kxX^P6?+_;f+|y*<|v z`8x*)csP8RzGwWK;Gy|4Wyb!#;&)Fs%=Pu+^$#ycXJdzGFLs~LnKN&-S06U9CjT8A z1xkz$(AWQJ>28{j{hseu^kxCTGrvgv?yrNlJ-=uoMZ0KCx@skUd@Wu1;bhiA0M*5| z0o>1t?XRKZkCk_)9Uwxt0X7KyCr{E1V6Q*>)l=ZpJgBZqZROSdZRsI;+Wg;XP|8|4 zsyS2whzl+P?_761Y}SVaV9Yz}I+vnwEijX|M{{30VJE-%M{|kFs^nL0)O|m=-8#Bc zKZY91U+hto(Acl4v>0kOyfvK?JGbdJBa%Lr&vv;+mZ~pKKI~)snAmu?bW}^%5Gmb* zEBU|vE?@5TSz*7KKoMEAjG~YbKC6+pG1TZH$ze44eRR9iTfDwUcy^7*A(+Df|Irlj zc~4hMvzK>Vswjvt6iO4qCnP3>iOVvh6T?&~)=q$_`;21%j)!-c_JBHo1lZE-xT}xx z8X7e!fW1XML<@|)58n8v5TFje{L@^06M2sh>lzTwj;847A@j7%58Yg3=@q zg2*+1o{Ku!fmQ|4{8TrnAhO2ta>)rpdaNidm=OEwe$gjUakF~N{|wypK{AyAf{{Ik zC)U)xCJjP`8X_3Dt&lg-Oj;&((+{hA^YEs1?B$ zeFi&r6&`)Z=9=Hbc=%f7`dZO?bDS=h)-#isio;E4Pme(74%~+v00kul z1pN_+>cobM>-@2-{EZ@^fai}`oCpjWmK2zXk~K&QxJWbHk7i=h2(nna-zE_S^wqG{ z7*x}6oC_-zTrFKs?e88Mr5RI~`02z$Cv)b00#hor%Bo$bi`@_9AJtc%SnbyJC2=!u zt)>A(09bfVgdK1TUNVf^7m4@xgvSr*$snt!I%dG|&}-KI{@FSG^baYb27Q*1ezV~@ zWaR>j=*~z==$`azpKmK5F~d=)OgaRADNbO|2_T`cT9NSN2Z&Y&;|Cb*~e@P(Ca9TaIisZzqmRC72gs zDa4W7jt`E&daTo3F*S1j^xR;4gxM1Mg#Aegk&zid5fX?X^buqsDU5UTQqsu3Kn@2n z17Gmx{4s*uZ;#^;wpnrBV0?Pt6ctYaADD!=SjMh`$9zvF|MRm^-Q>=y7 zIdd?*zje#uW*CBQ<%FA2I*qyjUvZ#HKkP!(QH*t$u7LwVB0Px?sbBCtAxe)8?M@=V zP-+ZhGrfLjbK574%EkH?~e!pBy)Rf&I_4re@VbRA@hE?;}T#xqKW_5lseh;#x*6U@7X zc8#OhSW2eMNrR!4DS<8_>|{>!)M4HkX{A_=W+JJN$G}Apn`Fu4gQSdN*y}vAK0eX)B>iOp&sMFbBjcu#i zodiSGS$R;(#8;0IuqAm%c%0Em33I}d7y=o~);~3$J~11#S)^hB%Iby%DvBF>ndNA8 z)+R%BG4w5Il96djw?!A0;;u%GkqbO>(O0_hJ9R&(LW_OWCQuRVZOUK?6zU8Qpa)Gl z8O-(ksc&!)j=5=} zKV2J$MnJDL=Q*}w07%P=RUP~6A1rJ^={ewbtrIyl{TH+(mYWA$y%01lDIEdfIBaD0 z2%WgirS0yac{`^sqib;W`0}^Dr3$~J!5@4i_t*O8kPVj1hCGB)ajtYDNPN^Q_XgtX zpa3IuT#XLE@;hiHq(o)}8LEg-1<;Rlw4N!>P+Um(UGp#rsfF3MlI=(?%CW;FGWZVq zn04?rFb4$1*eCe657&C%JLRd%=FBYu`8a4bL8~L0j$KHU6 z$itB_fvl*=mCKY(oZQd%b)QR22ahf*Jq?s*dVu5K)QIrKuk^7)gE1sh<;+HXQIUgd zkYf5iq937(wF|jJ4F@w6U;I4>{J>ZYIPPi=YyED8XAtWkbEsRFLQc+{9lLcU7zo!tp8idR2o8K{~3@`{i;_dxT@^=Oqu~s|2f1JB9z7AR-}A4UH!<3l}DYtYmqk9C1B# zIJ0f{f|_R&*nQhXz}fz|H&v*niso*T%>T4@d434U$@s1C@TbqHUW4U=EfUS`H0%7; zs#JUKsjbn&%FWrO-sjzFC6vrqh*FNlb~w&W+5LJw_tpQfk+d}AJ~Hdkt;U^uwZe+R zfu1;_5xFU?N%LV0Xhp4cmFeExVs9dn0r7y~wwKvTpwrQLGaItcF1GcqKrcD(8%-}y zh+W3LNX+D-+Ilk$IM%*KH5vWmzuL%Vp^|YXeIxFJelke=2)jBgB=J3B$x@Sv7M7EW z3VrW*c~lzYj5jw@+}pL~;KKmkkr4*2WUQ`PRK?QAnpT0iTV1ML5B0l4eK=H1Xn|^>k?2@#yA{~&vE6|WSw8~+f>d&*#8= zx(jZ>CFv$FWL~r{*dh9t@Zn)>f-q*O;!Ei= zBY&>d6-9+SFQ+WhEc_k<7i1~~7bTJ0xyar4R8$1OKIKjM=^=AqkXHoQ8C{U@+7DJjNfF51z0(+fkMvr3 zN!f0l==q9vTMYxxU8Sd5B{XJZVsZ}RInan4HaHB7%TBSG;RgDhZi>V7iYiB4Gd8W zPI-V;$^w@UtDEjwj0wi-CTeQ*Xb*R(vQc+}MJ8&$24)?B#Xk{{G*}Q|yYwxcL&UqK z477~gdQH$Nic1{(QNKn?k1D>&AT8<#EE$=I<&smUMy6~+<`6t8f#v7ii;@(YZaPaO z_@}dCEFD$6o9cmTc>?t>%R@E7%(#{Z7p9)m(ek?I>&WK?gbUu69D_5NzqLEwVQjLz z;j+c}iF*?1y&}kC5@uQ^a^D695x@@tlEY~^<@|>%s*;$M(`rgtcd;tia2y46ymxaQMFP#R!<`WZzwPNq^ZE$_(^fN3Ixfi8K<(XvkQkuS< z@SIEqpK(E}*BsnTA1}QU`Z}mMV~K!`4dla}9$r5HTd^QrA-Vl2sm2K91ez6k!coJo zHLI4mAk;)i?;9sYS$!Y!l2E*@!&t&lM06mnVQ=lGTk~p2A__1U_aL+|;f}W9O zgVrFax@HK9k%&x@9r{t;KAiDLnGY;Wp+qQ>xWP2hU=CvWok7XIjDN&b#-teK@%V-|2Pc2@rG4Qm~t<8~R)MNt<1ru-e72;WsAK~Q) zv&MGK_3hmYQjeQ%_?T)@u(*yi>Q&I2f%M=&Geg#a0&u1wtTTXH0H3SA!zheCdls7! zzT_YoJ9B#XD@mrrae!WP6Pl;yPR&>O3W;edrg&3U+m>8DXT<5^VpH{y%$jJl+1mzw zZWHhpQDlNp)T2RV{rdA}FbgU(rSLW27W+~t9D_Fm>`C*;*4TvpM2u`>?+(zUeo zZGuQN?$wno=i7xmU!BF*WWxJ8u_bV4>w$OR^inAmtB!h(KjIW4$+`p-oN10aW|@JE z_~fJqb{`gfwm(%3B-x<7%Z_dBHTNznVT-V-^+)WL7VzW<*Ku)xsw zpQJk3somCK^&GFwztoeXiYu^GtwG@U!UV&(no=EuVK-=|7m`|66|7tf%{4x5cjOwb6_14l;q^u=_OqcwnF1o1Z@L z*A~(*%elL;85H3%Q1fKLpTsAyx5vAtj`=Wo#6w_~SrRfio#{G@-AW+$M^k4PK;z17 z$Ge~_zZ>^r>VQ)+T#r5Rw+AbWCpEcs*xSaDl5m#GA2XM(3zw4_CQm!3Gz^>26NM}} zo2g4p*OQUh-`iSq;yzSai>+-k=Sg4VE~1Zfk;XNK+eV43?63Y%T1nt|{O@ zO(7Gg1}H5$5|MD_qO2La+lX>CPvrHcBcFWgXn%RHzFIM)y7Osak>9eU7e}ERiO;NI zSUc&n_nT&F+L2^}b!;%c-_{~o6VWMcIVZE>P?V^<*5CePzu`*txDq?YrQ`#R)UdI)kN5V z=w77KT2wBEtCYq1oWf&CDgwbr#Ux|DO}=*M9I-VT;rxsxs`)D{t zITV{xtx>bY0gpG$z?hUoWK@K9=F}D9z^LThSSntoKF=ah-mfbcVhG+4$nRo)W+|9R zJ=b0%8aSd<1zOB@;6geA*DaXYthPBG+>Ec9AB7wVeyp{3Y(#et9(LtT2SKkDAww!K zkWj-dTAFh*#XArbV34?Kn;Z!l5@sjc`LGtsU2F4aYa4|f=hl}rX^@%}d*XaKz8RJ_ zH4rubjF(xi=!0|KkyyjmC@p z)tZ~bPQ#8wrci=Vmq>rlc)Fihx=J7+GEg9;HiBjjguC0-><;I`*<{l% zR(o4jC)cQZ+(PMr8D^rdC2D*@mHgjp515c=*#0`if`yeSEkh`ya}N}hD_tdtbojG% zr)kF5z!VY6AiA0+;xI9(R9;(zQ9R~lg`1-bO^rGbUpD_?QF0W@n(v;KHqc+oGOEeT zF0d&hJ17}q*35My(;+$km8e|=!!b}Cdj~}Yr*TOq> z1JfWAj^$9JW?b&X%Cwf*CBgB24FhlsULfP39Kc`UFort!JwqT2UdRzDI2Z4PeYOoS z54wYw)As%ckeVxe-4GfnT;^3CMeg5MbtPn$kwfjCfyF`#EREH_|MEuvoL>!XT}`|V zK2(`uQk&^Wf${hu(cu$6Z=JCe-7z({6wUqX!5wqnS4nolOZO>Y8#L93wu)ej#7(Tb zjkwcY=IIl)zX{wzLs^R21NZcHZ{r8jKfi%g8lVI?JDC<-c=2fp-Fhf%s((OZ?j z3ExgfV5!_Qww2mMJ0?^qMP1Lc?)4RMb7J6|7&1ud;YrNm&sH=60=*ViWd^~LE{D%o zvtjqIzAK(z310~w!%cOI^p5$|t%PZ1rpO-Wp1ODWyBWy0g+m%~1FWwlCWBV^k{HaI2{WXTj#PgvY?+5XI;FR`X)(wHiKlXxdKO8(GewZBWoK#x@|U*T`*Z2mQ&!189LnA8=Xw(4 z>ORRM^bB>5UIOnnbqw)+9&%Om>EOBt!gmiCOCD7Y>VW#V-Bhis=b#BP*wHf(^Np?ZQH*hfds&Ysv! zVr{3+R?lQ<^j?M-sj)HHw>O#=4UUTpV6&<+jB!aVJ5_E9PI3}WHA;OT6Rke z*n*hPJAIg?*$eKUc_ucESKP$7wQ(iO3*(jvtynjkpnG5#SPZU5>gv@Uo}0IPs#Hef z#2n7sC^Jvbsx;2K3Rld(-3us1zXwaq1sZUuf`!3D)6f-+cRBQB3eQk!JF+>3`aI4q zuVqyb_6bi8GARRJ5l8rx1SN7z#I5}|e}2uqK*)IF$k0N+9I(>UfE??9AF zYw}PI(W-p7#MU}mk%3{#qs}A^`w2d7*n|a%>2T8~7G!j|2C7PTJHw8Pu?iSbGT}Kb3YG!4fM6zFYf1+p7ePLpS@InWcrsHX(_osnnc|Q zm!gOj5(_)A%uojx7zKuFd8d_8OZJpu)Ewr+gEv#n5&cw&rO3y;<&<*hJqjtN#(0|B z$mV$TKYX30kKRG?v}0=Mp=-!ecu%8vmVZ;VRdhT@a_xqFh*^Ylzevs$xup z;#K&9p8vK#{&jGKo^R2ZLRh?PKjzYN4Y7$5*RR6NZPOd|Y!9C}dk?aLAyiq$dCQVV zJve92XEeW;>Hn$)g3h#72tKg%ip-fri(E! zq=zY+4*mu=#y&7CQ%jfJ(HRdg;4n9BXfx|C?MEyOUiO6!C8JMsP7)3a;p1V0tu*H4 zprPD{URmzWfy;|oUMzUg_PJky_M9X1o9M3PXDtPm8jxoj-Q2?d;Q(IzPf{>#fuMAZ z;vJtU-DX~Ni9=7V)&&tEm8%C6A!Pj9_2=%4MMhkfJs;upT(`Z-%usz?qA-Q!c`+IG^*GxH7Qov zh58zjEC7<_RJ1iU_F9;j3Siqo&fx~!ObDSGMz(W5whY>SgqFFf zm5|aq7uaA%^%+FaTnrRe61?EKR9CO`-1Lz)-JWsFugWFW@4TY#fwfQ$He_R~(Wabx z2Zf5(P;ka4C{sE#ntDXNe(MJi(L2{47-JZv4M(1(@0PgRjFNxMP2{4%7ivN%4zg0+ zf7mbj-s>gD#(c%E#C;0{29K7p^1sk931#cNtR{{ca=S@TdVZ@$(bq=iQU*!!>Qrcg z#DhjCpjD+wa#=@d!m-LA3kJ6&3c%{o`u>{!mk{%x=xMsO^gh37^qITe_IYq^=1<^# zYzB<8_DlW!K;KXPCsz{qzLNW04!GrPSN%6=Q`T%y8CdU zmg0YDH=XOx_o6egey2lby!RJQ;LgBVM-zKjpt;{ZpAUQ4xO{g~`Fs7IC~WzAG=W74 zoh0vzX14ZcpQmHHuseR<2n!zCKrp(z#mD-b>4E$1+}vD!9YDU!@ZDlWUc0uW06Eu* z`G;cU>v0T`?<~K^^KH3u-OZB^$V9(u51-AO7Qg+E8BcRxpA+6;+JNr2I*P5HPLTI8 zY=t8%_P|Vo2Z;N%DkaLWSB3Zi9Hne-bf&GE&lmLHI~9x90jugKm{jO4vCA89&v}V;O9!{*ZKP*--^wZaG|0|#j@)06Dik)_ z!d&{AB8YwhWen!mAZ!JGg0OZeK#`Wq2JRTV$6O*apb@(Q>i1sm+M|cYl{4c+ocbI`kYCRiK?ChDH4z=A@p9h5q{Z5IYfNA{R1|ksW9B&yyoz z;LQUCrRBV2b>;86&cQX{gxTb1N0#QMz(vE`S$jnhKqv+kohl1gSsIX`WD!gQEtifYP6Hd;BkcezW6-JqM*ZrHT zn-WYW0mV@eu|yDxi;z_h3K1GirCVM<2ddH(MS>~|EW4uFu197YYji&OLY!wp( zHQ`rO5_62KC><1tB7EwTSKo4h7Y%fkYr@vT~w3`&@I2+`aRO#KL?6U z(Yg~?SGLZ^h!9R?y0+i@Y6#tDFI&X#@Vsz#UQBXPB8-JN9ERD*E;qMB#BDuUv4Lw`IuLSTo5&zEb%5iNJ z3^jF+cZalZXD->KD&;b$4tfk5RO|~SgM(9srsX4as!N##pPO?TA%&%j)8|2lA4&$n zA|yxM;bY2;DI2Vv6$TcuMYPLclk9Pa>YBF5SzlgZL4D*P zDyDH$`4OA~&ji#4j}0CU6Y-iIr~d?0I=yif`Ra=C705OygQY-JktAFSN9r-zY>ek(^wOoK&=2@Dfe{s< z!x0>No-~G_h3qupSt#9C3QO|}#v+mEf`Ji-hW_UJU_2?}AP)2#deRF+am1&%#iUY_ zfEVh)4Bl5ZDYk~qtwnAYNSf(Hr{RKlH*V#J0wSasuMNw9=r)-0?j3BzEyZPMs_vYg zs$r*(-$2i@8$3w;Si_<3PehE z2@Axs$0KtkwQdv39+*OMW5o?V_~Y4?n$bBydj*}(V&*CQwrXgO4obI& ze0H%m8L`voVN>_Fpf3qByupLAd*>~7#hrXTPf>vD)RCXY3UH_gbw3@bf=r9b7U4@Y zK7y?kem2Y;T@Sn!Sbemh3LN_-{r}8P8pfRt{?G9S{MRcxAS;^bO}mMK&{#q+oau4* ze)szrql2c*f`-P=5N&wgJ^jM|atiFCXuBala3%XNJ#F9PcShce$UysPDxxG2*%_ z*Zt^P)2^fc<{6<1E@%^MTd{Rz&f=wxpM zE=(RFIdQ7t-#$dN%2;0E&vzdbfu2L{?w8@4IYn57h}A^9x3iU4rxkt_k(S>YH6w*I z;WedPYJ<8KPfu4*TZo7$6c?D)mN(DQpCtt>a*Fj6j)lYrKXlFC>N{TdgjKGy8BVJ- z$_dmS!I3R@XI7Xq-G}fV{@9XcUq~EtTSqjm#8}ikv9QPHmtQs(%kZoV(jMgJnF|go zF-Pg&OlSPYW3_ogVR%g1lvo?-DrRXf6!`m=F#U+(_T572fi6XBGYi7Hg<`9VFv{!K zyZ+3LMI@R@XNS0oLg@ycmm&2a*qfp|B~1jDT2S1xn1DbPp@39iF?B`+BFl*Q^8z|H zt^^YeTBF)m-KlemahkfcnTO#5pFQnLx2_3h2JvZxgt8;`x1k7wa?qduv8<4Qk>4dPkfYp@eAn_kkw=z&~%^H?s2iC^yp$PWR`(FdC`S-@gQ%p zne&YCVKVJKijj%Ii6s5W=)30Oh;$~(*(UHxZmQ_c$c&K>Z>*KK^3^wLR5GWoqUE3p zTQbfg4El+CRTTFlJIP82GY0ercM{$t@%%u4T~sZeHI~*I42JzrkVfzeo;7f1UKczYeVYkPAGb-Z@1*_=j}X^9SyZOTo{fHSReQ(`_Hl4^Zpg-U7I z#!&Y@)|lVxiObr115PE8VdezAFlc>qNNRX2^3-`vHRe>iDexwMq%2aNsU;G8-*@FKpWBu?+?(tjj3zj$>FZLwPtPzW6z>vlTa8VQ z0)E>*@|0Q~qnB}57IpbvtLiTgQSI0>?2Uqf2lzDz7LG-3`Vf=Vd`f$!F!FV z=7B2OPKI+U9p+6xBgNefwU+(*5PK_I!8PP$*MknLf@E91=)(UZ*gIaq1~8DZXl?%M z^kxLlf!XPl+fN3kStywCLg+ z%+$$msnj8RpRg&d3AbKH5hzXd}CbffN$w?%USZ9xifrb1N1YobL?s^1{s}N&=J;n#6q^qQ6g)FBp?yA~P|eGQssZBf~_~m=5WnBA}21T~ZXT2$m%8 z>c~diIb79k6uRV3Uy)(CBL`VTZrS1)*doxOfuE3Ce0~&x{UG=VLTT_?7k>WRB#y-b zrpSYO{bNk?E=_6Kur-R_m2u@=6J+pvXK_;U-1X@e8$op`9AyKZjqF?WH?I`bQkPY@#N4VcHa*3vMV3t zx!2gTs)o`}^7TGRQ-e~!;v~IqL~TIkq1L&dR{bs?OGC199$dPKbJ|TY4qziIfBYc+ zLELr}TC79AsHBeU9x;OHM>X@q@7C!5A~w@4^!NRhnw#1!9v{c&)Bpl6goShuL`Pr{ z#6N=S(z3GUi@xwrjZEhc##O8P1ajuf>+49=_oGkwF!sL_>2Bz`txl8jK1aie0}$TF z|EEWKh5iGd#SQ^4A2873CGa!(G&!4`^hzW6h<>``#{5VeumjnC!Y#S8I|P!B38^j#`A9n!br%!t8JsUT-H9nwdlDo3vYkQ&6pfj z&iqp(Z>v_Yb7(=5g{{vbk&w%n7%JJb)G4l!eu~7Eeq3%t-rOZT^<0Hqp7mT7s&_pt zAyYjruHe^Z(U%@N5_#_;Jh8Of-ZB1Cm2A^&M^-Gk*m8?>d^$L~S-pC6GtE-2C5{0D z8)$X^P^KuzXgYE0KD)L5Oja83o%CO?KJQ3w@z8^*wg8ukl3IBRYboW*T+up14)ji# zttHi1qlyQ~DCz|KrZN~N(?XY!G!Nq!v>$v=NK1_2A!E|qT4NzXNb&kqF9{@;TM-UO zm{XHg!+VD4;e!+^c*~wFXe^vcj5;86Fw@GkhMX%so*9fNfI^ETT*%1^LXwPdk6zk> zYKm0JPD`d6B~cYRR(LHi)Chf57-@_dHx1=rq}c*7Dj}x$i9NF#RdE-D1_+wsaXxAQ zR0R=?5-r8uhouch__}QBLaU`*>=Xl65upipd|0qaJ&#Ol;Zfa$>S`k40nw6Aa?pLE z)JKDpLTD zFlrH^gaR##^?QO0@lg~_z|_tUT0)b&DCA~txta$SpBWaB$FnGf*?~~f(~1rEwYV0q zy#YFEco%VpKWOnglo&Vauhg5ep@&fj_$_cdu&nNn;EPxuQ4-fI;=DKB>OFq?U+Ep@ z`j6(Y zT0YP3Zi~V;CWhJrQq`pqP7ksV^~B}@N+t%%hrXAbdN}INBNbuIii@yhLFR&JgV5#Q z`iOcX_1-|I`U_Dk)ZsT32U=+W*qj&ad zY7-fNCoTHe0{+CDNGEG$VIY_CG2OAsc&i(k>|Sb@77K}G${v!F25qQ^@(R~OWFW^7 z!unah5>;^sZoObV5s7w~Wa#-1H@7(>GFlA6xMuA=TVXA|JX(9AIBOcwM_G;wWJn8k z!Wz*m!83*0uyG^OSmX#Ey1X-}zvZcFROCLVv3X|EL)9xc&15KJL zfJ(eGzrrKxDFTmLq}cz@1pxm8)DhqpUb7xgnbw{pP{ZBW4v2Q&g6z%W5)&TNci>LG z%~7Xw54q5tZeTVO1gpT{;MKDUoK=3S5W*ta;#Bz4^XT6i8*Ei-UZ{aQu3M~=^y-v{ zMx#YxCm>YvX0=cfZOI3dGBr8qRhYzfTxJ@omH5+$l?-vj2bGZ~$wv1@3E?fx6=VgR zQC*>!pZB*;f&!xgs`9uBngbzl zo0wU258GbSoO@J@QW6>20fAOoN^q%AYxK|_p9UPYT3Q%DK8WNp#`+<*U*^zr*&yrV z^g!Kxl~4HMO?X927A{EIIm@#)-{??BnWQUX@6s@#R@ro_fLWI&*%4s>yNI`4sGWZ= zmgfSNqR8tFoAg*A%~eTyt}iICNTxpUFi=*N3qx4~`~hSe!g1PotaTxW1KWX`F{2zx zE|L%&Ua;ChjZ(A=8;XovXF+&Ow*Fu+OmHb()8Y}4-%VGId^&Qsvvmmc_&c@IS71% zpkiy>BQHB5fe)+s`gZGfC=TMcK#h3ASmV)&GqJ-+^?DDbZ&QoPo@-bgGd*n$KNz-- zP;P0CHB}V`8D(S;WYypLLFt8b0irogaTB|S_hV-tn%}bj2Nw^_yS4UxhOY&?e_wnL zAeUxzW{rRn-~o34|Af&O?(=1=UmCybexO}|0)|+?EeAm>7VAe{r&U(Fb!n; zvB57m_gS95&*JT^N9@o4HsjRCvvmhrKF&vS9%i@OfuWh6PwDZ$K*&jQ?E4_;+}4LH$n5_#dlqq`zwa z5p$56zc9U)4Ok*^dALm;7|8o(gkR~sjIviqJ@?a=W2JPYTPGzlwmhg zI-TTP*3?v7xlXU9HZ8y18s%C(-7iKN%9nbXb`q4gFM9bsEO8y5cRkird{mirImj}x z_0b_ZJnc9DE$x$YzNRsK%g@&4{FT;h(MNX2o;;2RzEm@Yk?Xa3vvyCbAFr2>TQ1p# zUH8j*%U>+7>$IjAnlY#dC6hgk@Mn&0EHfE@B84QyF)AXW2Iq8kn^uT*1-d8Xxs){w zCe|WKs3O)UyyYA%hrb>4lb*iqEix8gdWS6`$)C2jEkOr*v98EMu3D|aTQ1Ssa?88P z5j)g?%dK8_3zZ*K2IRpbEOrx0{s6pho^e~>#pu-^Bk`-TTjgcUmCb+;P=aCBY3ACq zlZvk79Tit#4h%!fTBHDru<;;_&1=>Yj~Plo9}tbh3!4SmsxOZqdVIL4zG27OA48$tbxMh#AjBD*I13?dwPV~#p5>&W;!QGenB z^C)flR6hp_iSk0ckwC>>b+5`buy?Oj^Gt4DrfrQvgk$R^QLKP~a*&e1k#u;K*1T33 z&^Lg$&hrxiBgES&+B(_YYv7)7f39plpu}RfJip@B7P^sJ&&kPQ>i#juMR z^gh=MimmSJtrl4+&+COvBztI5E!@CYmL=Y~`RIDJ1u(OX)B!&q?17PmYk_tb+S2VV z`ZP&b0yh=e0-cGW)LTO#g2H6&FgEG2$vBaBl_Y?-F+rPsLQ8=G&$C5CVI{5_J2E%N zu5K`1hXWQKPy(IRV;>mWKlbxXQ$)lbrU}C`WVgf&`+Jkx?L+X^8ZnAKb&@Zk-WJk4 z1T^yTUyJ34VE<5w%UWI5WhIL6i}6yfaET->E6M@E>ZrlyyE;oIvGRd3(6q$_+okcn=-LAjA%>#Y*r#9*hd6SGS4iaLe}aH z2Uy%-*|5#g0&pDD8;KahBiuZghKZES1bWo*vn&nwf4K6Brb0Uj%CPpRiGN_gE!OAj zhsjuLfzlCU*fo&8>#9tPsZgh@b ziwMY+!K=|TVG@YfmoI8pb_MXyKvX@dE7{H|| zkAO&4x5+Z14S`~7(SotFZ&WRR{2~i4dI(*GdnnYv)=@be<2ZJrosPM#2T<2z9laGB zs=+Fe_id^S{6)aFelK>5HjOVdys9{bnykpKOh>b@~;0o9|of+nZj$%@3U~-f#+p-6f|8? z4dJy$cf~3-(k4^Wib_%dN)@0z%)Yrgr*eSK7kSdfRE#Pv zQLM+E%^14LN0uaYvUqfcBK1D~{Nz0y3iB=82wt17UMq>f5*5xmywYEbzqq$iyR0%n zTmnBW^}qhYVqPzv9(j!?zFDw;&3ozlIezihvfrLnJgB2_e&F%@74yT={@?J{t(yVX zGQ`U}a{8|7F?@ktukia5(RrgfeQj;_eATP-J@9|?I~Z#|d5%5czkl;fIbL3X0mN#naK!cCL6kY~T9uKf)YN zpmO%Wysr@S#(n0u`CZlcoF~hFQ0;tqA3x^$x%cP3Xm9uBer@*Ln{);LTU`eC`KR9* z_j89`Hjm9yPY3O9;Qd_V6sKL=y+2d9KO9ZuR5S1tvvprj^$`d7`rIYse>2+#62aP@YiWx7 z^>g`OpU>{@@2_;Fmb4E zC7ZO)MZ<2Kg3S04sy`K?1#uyq)Tbk{ED#Fc!8)c{W@;sLcNzv7HmIcN8|+Tn5^w^T zF@a6gq9eG9C>g&Ul|i)cFeCGrInx_bV`~kc;oMrSwCVD*%XUOA%-ReJC4e1WLeIu! zSlTXiqHt_agu5LcdD6#ZJ2x_973yYuj4&AurERsFdVfSLtvaF2v_1tl=fiRD{j|#9 zrnoyh`&k?X=R?dy^v1hJzL&i|%d%)`ZkZJvY!KJV+rTB8q!moPXL~t-KTMd1pfqH3 zrKX0G@RkJ5&cfF4e&UXdb-;|-<+GfZ4hBqIe4d%O;lVb!REd9Li2 z)hxZ@tAp(l6&Soki|a&Uo4VBW&d}xtDchc}j!`fC4Avy{1@;D&C#$&Y)AwIA#r%xF z_=Er(uY*_2VDPr?Hgl>)kKYr}29Iv5<^R;^hXD;(3NOV}P({8T_MZT3c!ndEb}~-+ zY9zz~NH{XapH(d1lKrPK#cx)Sl|eyK-P0-1!BzSy6^+QZ)ts|U<2k2S2u8}^psA)0x4&4&RX9KX zNY`18g-LzxNu;4nrT$UW|*81`#NFl z?RyU7rS}9C6WQ%wxG^sANHoszc^lcrUSIg~vUh$(4_4kvOemjP3VtKt$lh2Ip>#nc<{~K?yobTaZZ`?13 z6H^^-7Xf}BpIsdjT@(HMFhG*M`D5l`AmWG~DI?O7D329whSM&v&?CUGx5%E2bfO{RR37a~-zb zb`y5RKV#R^bgcJ=r}wNc)&%5O&h7Sl7vi1pQ?B1y%@_1@=GC1&@GiQcpJRPb*I&xn zr*oUn_<@|fyp1K^F6!hiYq)+GQ}-f#CqO{X9q`*5^-}-x?sxMZY1x)yqV%sA?eKdx zT{^$o;Bz{-FtXKe!k(}+La*9+nO#}a!?X1nY3XYAxEbnl&4zoc%SK?$*+5tkDwl`A z_lGEBDlstIyo|22+1j-Kc$u-b^SLMR@_t+Yx`}*nBDh>}`_=th=g-E=C=Q!@u3L~N z(4e-#*kRL19c!*|c1TCRVF1vKquq61;L>vC{+BIgYKbkgirnu;Nm;oI#=<2+o_=9y zx>TI|e)f{3g*(|*C?2I&p0k?fqM+cE{*)DyfgSSpFysO{NgS}RX7uyS7e0G_*Wan;BHvcl+vvK%0!B7~$88=&FVXyF|} z^AraqJNOE>iq(A$)fUAr*vxK{C1lQ~YDhxFS_Xj*Pt9a3!hESFz04I|S;xQGG{du> zf#R@$(oA<^EV|J+S|O+`(h-`brB=C4y4n8&Z~;vWZ?TTt(PsSj$FKyx=PhHt9TBEFKM;rAfjZNpX_KSB!C-@?( zY|`i(W-;X0Vg+BRxepz4Plx(OcOf^C=DKK<`n;u zzZmz91wSw{cJ~NFQX+pR-F;&^=Kn3l3Vc$!K0WRf%?hnZpb-WK>LRhxEoO`;&uUZ0 z1SPlJZZyfHKN9v{)9+7VCB;5GbIj#3C4skKy3Qvog{@ChF2JblTY7nnA;HS5wQ{z# z$)PyZ>npCtrJUtGgz-1i94)jx5c+>`-2!p$*oab4hxB&VYhlmQTzzC8_r7u?onQ7% z98CK{Z_>J*iU_wMC1F|}%G3-$-&?{ z{fX}7wsQTv8|uXAn^uI|*o46FF!3a<<`9gnD{ zsVnWF#~K?{VkOF%BbIDH@kx4m`b$B@r8^r}51@Ie4pS}L@6v^5Rtip{&68hBhy)1t ztSZR-)#gjny`kx`@;x{`)Pi*)Njrr*PJ`bI5H^LJEXFJoO4(ke9gB zr~+~hwkyV}s9m_Qg50r%XJO&z#7(kisHXs*tO*X@rwN79u^4}Bht)+b2lb5q!eZ0$ z(|AJA&T)le*848ZBHE&h&G`z#j7&6~%Tl#Yh$;GOB)VlBOc#tjPJ;r$)P#bc*zZF& z3W9HhHzh+TnQv>5#iFp^2XCg3ji?ReZ$pTZ6y2*fEmcXlTAA@f7YabnNiLO((W}rx z&rR;cdm-B9R)szvU9VFNgd9kqM(u=jN;62dkLnDkOVB76rnJ?NB1qJ7s>G$3XJtjA zXppbwnW%E(q_Sma^+4l-6DiL=D}W4kFRB#hBtvIqFbFp|#VIkshPHB@1XJ)@rOh5W z2;pSkEwUmsl$w;PyhJVJWM_CqGs(m(u#(U~p86MDO88DVq)R(htV-cWsgfGTtysg>m#6 zsA5b{Z%$uDPd`)f=f)g~`7*D2fmAi^;jOjYJuG3SSZ%$}Y2@#9*3B*#*@*VOTGg^( z&4m2CT*S<2$&{5Q*KY)5LL$v!GCKv9tosYYf$#qNY9|W$em!zSHNNeFElI@%t^PL$ zXRe*(+k~*dB~EHh($I2!LjT;hct8et-JLk&rf$Ux$@}7HIL_ zUft9>L-!kgjHEvU^Sy5941514?>_F*{db4nuIEYK-t&Vd@3IH=?ls%CZGLnd z*$dDGc9O!JX$;NOI2-!4uQ=VW8a7d;FSGdizOLGahq;-RQ*P z!XvO7X^wM|pAF-~KCPt@>P&3pkE|t_YbvL<3(=TuUrYF{AWcJ4a#1<9I65dDBleRA zLY}8fuEQfb2*^G=IcTtqnuT2#zMnEqJIaU?RXk}D{>s=!3VsNPjD)dGz`yuCRMyj@ zxbC6~R;MkXxOn=T0?0vb?^@?nmMx1Ft%(S_*)2^0TEWjD zEr4vC!|l`NIU^Tu)V>*YNq1}9^8qQsJD%T2c&=rz>?EV?Dye9ITsnEpX^2vw6anQ) zCFhOYQcki70~H{=`7#oiw&J#BugGZ6SE3y8?32D3nBIYZQo5sBxFN@kO&_^y;;)uV zRjN%s|3#y6K98L^fmd<8CDt-Mp`d-)6wf&;Y}P;YbYX}y#;VlByovT85H<8_entn{e zLF*VrECTvVFuP?eG!&rS;>zziW3I?4#>P%lQ*IWw+A5vVst#*b>(V6^HXf(Pf>};( zs$t7uwd@y0GI`n`^lpUpI!acN&OerAh$J?0F8_E9V+;*R^4;Sk+1Djt{Taf#=`Qrz z&8febnVHMkEbDQLXy&7;ZjFR<`*!V$GchXxcV>>g1IRc+^PmLq*+c@N^=X=s5?ryx zLw@J`xKF6Z$3xkHH%B>kW*w>X!k4le_J7++9)d)~iZ0a8k*$r0@}_;#YG@F?-}kyJ zF%)q6sk!2E*TEoi#98tC)$S+j*XP;1p`)$6^L>`&OWQ(^w*fI&v~$`FqLJGbZlhq7 zl!_xwkhg@1Gn!jd@UpEz*;mBeH8^#kD9Np7Bsuy9a4BgK!Mfx04=>9SK5?Zr4K$Vj#-twy+$@U1{%?@dcTmnm^GDP z6t2NwP}2@%2ogJPwNyLx?5|e31x=yfQXJbSpQ+)tw7ec~5Hx)k=38y_zSNHWL5Hwk zm=q!NTcS&T0FmA?1u{zZl3T*je@LEZKp#@q)IlxIiabsZ#FCSPDN^ z!g{}~kN1$<%8sm@bFMKC}S`>Y%5e~|Z58Q)77&Qr zb?0z9`(Cx%o+E)tDV~WOZ!pNjy*Zwmon9soz*MX7Sa{M{!R^JHb7bt1v^`n+^=scx z6o-N(biF26W{o@@a6fj4Zl7`@P+>>-8AH?An8UY=<-YC7$Nf8U#7z2K+N*lf!W@k^|kwVhA(d- zJ5wI^9y{>?FBltrdI6;SIv~icbp*5={(DQ&2lrfl2Zeb0^WP=`mLCrUM{f~A_ZN!m z_c8q>y&$=#8CTEfYuY4LfMAF*z0tAReLd(x!-^xk-7%dBHM5z!ZV_GqhPR@-jI?jf zaoKdf?K^~wBFH1~T4RyEzHY~|qv1l#!qPQ#FmeG(&RNWLrdsLLnc1WK1|Tcx{XI1f zpvV7?UrWG1RklcnjzJ&%1wW~UB{%HwIl0X5S*?HaEa%r>lLZxAl1)~DmE`T53LdC+ zJSR8nwbn75KkXq12EU}nL!|Z%%jGiue=R_T%+kV=xtofbs@;;s*Vb&leDzC-fgx1b z?swWgth-K=S}?ZiS|0o6dfdB)A1=ZH|D8)ouFFftI8OUJA|lDWdo7;Fyz$K zGe?j1BHu$HvS^6UFk__zz?wcXs$#6HrqGUNmhdgAAoPoSYyh0#@4hzc!7^nra59P0 z1hkZ!8>DCJ`1^TAfZ31=r7XY{93^E_%!pFUVXi_^Gkw7rAi9rEPwhuJ7K7R5piC&H zFKXdwM@6MPS=yf6q3gDoVJb&WzGpsbZFjdo!+>X(b(%CiB;6%l zPJoqo?57dMS;bP?OEYJ;+-8@G9lO-IA!awiyV;{<A*>I799Ci$tt5H)JGKLn@5C)asHWW0tKHbG;`eZ*(d&W>LG-wzyibklX|t zpgh>D>BwqeJo392z|vK2g-=joyJQ&&JY%-p=T5L?N`8Q1oSjS0T1_&qgI|rC2HcAk z>#lkXvVJWjXdDgS<5#rfWv!JP!~k4!Xk4)$x;3Qk>Jrt3+lcJ3kP_<^NP`b(xW;7g z*xe>Fhz#>Yr&4Ezi?z#8kJ#;D6H(_Igew#5YGe33%>?@(IpMr;uPX!j3(=6xBK-eC zUhI8SjGiQ?oix;hth;_X5*&IFou27+%nt0wL2+POA@)X)#ZJ6!WOE<9g2;qh* z37|Dii_$~k?; zrZk2K4Vv!L@zrQw?7{-CdGu!mQxbkRZAbp`9;};V(UYsw*Zf}%;yQ)fJst4I?-JL| zchP~J;Sx#?oYY8#NOy$9Xv)@8my46KY&;&o1>7}46LwNwVw=3qEE+D3c;FOeT+XQ7 z@=29yXa&A_Gbm^JO_LJx{*;On7{WaeX{|9;w(O9>k-?2)%JLxRU_j9^5N@!Md9Do|k@bD))(U~LN-j246&AVln@`_}8 z;{6~~cOWyA5}iA$dz)k$$O|$h7tY@4w3q3USZ>qBG#x@1OLG&7Tzl6zF`Cci|H6JvzC+fqSa`$H!d=+$9hYd06YVTz$9W{erCxTQjDh zu3`Qi?i~!#X4mg~2Zi2KmgjERk%q{9yh2Wzy7ZN%^EAc%hkkkP`@nu*Zs4k zLC0KK_CXB|lA_0+JO58iz*=*X;+mdA+32VURn&?ar5*PjPS-A;82UvG1`>X~m#{i3 zC)DYbL9^X3lO$~ANvpWZ@Fr=bbfmgyu?DqukAgCR2iUY1^H_&$51xpUK9wbTVVn|F zTwLH}k$K)h;$mALtXC0om~)3DpaB1GMAYrE@VBqxZAf`Ylm({+GE~Jya+SL^Eaz5+ zyhpvD37YA?k7`ypET_O33h z4Tc8YgRJrrHjTC{Uvx(&HAolpWZ2WfNw?m!*wIjEs_M1XjH+b*@cY!a(YVN9S2*qI zJO-%c~>ey10uCoxJ?YBIKjh=QLF;m2O-T3@?_m_T=VKe(fXskm(2`fVE zC}(ARW#;ZBGd(l9z9{eLh!~}q+HgpiN#1hBa{Vbl%gx>tJ0IP+MFbGKw*VCAJ*D+i z7;j51^}B|v#KB0y2iPh(RSRD*?2V_2nGJ?y!Ft}G8mOb*=u|eThXZHxa#dvu&po6t z;|pWf99I^J(?=jtp9tPIR1`99o7Iewk2PY@$qv4tjvFdv{Tn z&O^tZF+)KLTRx?08iVey1{NaK=g_0e%u0syIK{DH^#;Y*%F(}rWPJJvKPHWaor9Iv2>gUO{EzZ`51XzTS=r-m1<$j8wx&WL)I>b~WFf2!|6DjGCXr{P2Po5l1Yn z9w?`{OtPsA(Q>IQP+SUEGLI&ln2+})q|ktweCEL%pLsxc>?Jj{AF^nX!Gzf%l0g_4 zwiUzFdo?DwX>lu5VuU!wWq`LdjvP}QUC-BLpL`MYB=j!B55mouHtFfjG7TC%In=pz zl|t>Xq|F$gnOe(lcs+;sS9uZW&;j=Lz@uqL;@y5#D#2S zN(s(T?fy-RQ+cXzUG>O23tFWf-ZXJowK~u7vDd`d>Xi123My5S`-RE^GL;Y`uM*-z zaU!uJ_~tk$>BIt=$e>u|DOfzf7k*rF?$0F=-TC7>Wd>~saQjFv(pEoA9hHKs^U_x+1fm^UL+kE8!8P& zhRk1di5Tuo^sIu7HP{AU&nlearS^E|4^~TlK|0ll1H1GIC;szn-LJMhKL(H1Ek5~A3$SjDP1=3$`sZ0#{=Wi4=#%z;iR0+K8Z$JmFl;T` z*#`Ug$+I_viLgEMCcT5T^C+;o(@*k#qj(*X|03>xB}wdO^p6}McD(F>z>@#G!jS)h z6Vx}rk1gJdiym<7@W%YHclGYm?QHQlfaLf;dJziU9pY_2n%4QYzyuh+e+dU=%<8Xo z(E`FZGMBwMIb-cSo-?&-vfI0t-1^#J~}{v`f+ua zu*LC@f64!{f7=jm9#GsVv?^XLIty+N|iT>r$PC#e^Jio^ZQe) zuD(amd4-<+1J>mSjDFaD=J@%FbHk|9O&E8VY9ZMI7 zllqHpn}YlL1@vLWy{y|;y+&fhpYS+$A{s$fi0vn(bU;ZsP$NpB*> z**(l=>A)LM_~RBt?~%8o@eqkg>c9+?+R0~AlkSXIc!?Pail;V`IJr>5a$}z^axD=& z-}ImQickG0iG(jON+K2graw=@p8hKA_iaWo8o`q*ImsQrlN_HFxZot`_U$_yo249= zWoX&2`Kb{ZQPmOn*gUCZc%WHqf=U)xJG#Jc}%bivZUlxSI`=m!;qawo9~SDFQK z;#>pfqhzV`ghW4IAO`u+L_;EfJKM<-mI)KZ><@bW+=I63N=zKJB}|AzUqjx;S;J9u z^L>BuO8lc7lA%M}(tZ@}0mZn-1zbL-ze9&57uncQcIEJw z%U2bt0G73n%Ts9sl_H|k!Qk*;^!u32XbNLW?l9)ext8%6SmmUYHSH#+poGN#C?ajCmFr;H znWmC^b2F^QB2B_4zNdE?+fb@DqY*_VoJ_k8hm`2+G;|uKTLEsZ_jYcfB@__NiDcYU zbSZhdFR=Ky0PJYCj!2}OczDBultfc2#OKl+&UK#W==Kf@$EpZ~ zG;xtQ*N7Ar+?Z_KF{U&$R1GIOc?joKER~D5zqSPxKian4m0yw4O=5`vn-J-Rn>!5X z0a9fx)8=MLsM+*vDx;!F3E!dtN^R`Q6O>X=Xw6m?Lk648(G@(K6E=8MoHok|)jx`t z8YDL=G)5*cC#ygh}Y#=^@zBoJs4jrJfq+{WvKQZ69$_EBhG{|c;!#{KSM}`vMy8_ zfvlRIJ^2X<39ZJy`$;FWKa%4EB4@bH19rhLbChUUlZ*AVlx$v6HJQoAy8}g*vLuzT z7LAH#DMxMRQPq;M9IK7+*f@~LG}M#XV^1S1#Okml^(kT3=qZa4z5H1S25i7$>G1&K zYLRvk$zk1OhI(j<8lkw39%5KHWce65({k^<{;xhf=W4D^c{)~NIjz3}N<@iUwp^vbG(vSqnw^coio3?F+qXm5@NjAW3);CkCUn<_keAm-lnCs^rpOf zARZ46cD4v+sa5)SIQt=Nf!NS0Bbm-_+cpxf!+SDDWu!eFuA}o{&~NIN=;d<_c=F!) zAoY#S{>IGA$jH#Zc7FVgY6%P5$;O%eU~;nWb~u)*YLHGmw#i(}NaUiLKc;bC`RDZb z5+3$s0Q`0mN)a;t4U*QHrt68XT!LmPT?=$pT&R_p)^t12v#^yTj+F3XBI^R(Q47YR zM6Fs}!&s?b3@ZKd8s)5{<%3s@0#gB%sXG!0GFtQvaFM*TVF~2U_W8bZ``OVf6+jus;xAG&>`#;OLH;Gl-Y zk1#cikBRBN%qs!!bN?xUc@OMqft^Od3q7IEhsRnyzqh-}!}HS$-METa4dvBBSXx>Cro7JD9MKb9EOg^kuJ=ep5aj75#$ z!iM|9jpyj&l=cWk@Mv{=fk$9I*P(9w$TAcQ+OiQ@@1c>*ZZ!xDcHm+n;7a?LBL~S> z`#S~EAwQHVEGYu$dOS0SHZZltg=n|`|9(jtJR*}m;BqitCiEnT=6S?Wqz}3aH zt4ZnTZ>AQoh-+sWchQcuTi$?QbU<*A5u9oTGGP`#zsX%sq`;n#(kGBwQ+0s~Pl&su z>f$U2a;W>2i2C(yra~HP;8LyA#JP4AuD^vBZon6KGVwiFIK9Z%wxsQ}czax`B%=19 zwVcFLF>l3QGNQ6FDCH!8d)N23A??TXz?>0^H;X70fF%{jdGcyCKJUz%oS_w=c0uI8 z!&(*~7jO60V5cE8+n}z4M{~>CuJ2>HF3t!xr+k>woL02sRDTC6Miz+FWWZ}76#Fv7 z)ZUR4Fwo z8-yF%#8j`R9FDXfmp$A=g-(G^;p7nI1~*Hm+?))xMCYA=DxF+HU0;)^;%!|^xQ)mA zOJYmoyt=%@S6HhhIf2i7ZWkOt${C$GZy+d~@x6Y|oRg{>yTm4;U}XnYs64D zFn_c(WK{SZ-)Lt-woo@gk%#jYtWH5t zmjXQzS3etiVI+K3rY}*yI?qNW5m#I_#G)c3GxfAke<5Lw9>3lxwmqtYUxUu;3tE$j zxfkdTk=Z4<2iopGpey41aO+x2ViWXVu z3Nhxx`C^~^78Se*UTWgyZCNL6#TQh_s-~2iL{#2!L`C6^&b?Yn{-Pi%3#UBLSbRZg zuBcKVl5*l<;;9O^=`6F}W6`{{&(t7&Ttrm|qmb{LwU|vzroUn8dx)4QHXAPEE*5H{ zHC_>|%#;yFpIl*GRMc)!zxVHHcpNPs%j zgs~plny4&npVPrDD<&_dD+P@JRuihezhC309dK+q|16c$tYc#4iWC!hr0YrNrlt@F;~V?ssD>aWxMbs{WI;5QJ9W^KPje?)3T`x;E}w zH+4!*`wle`*}00nibZ@8S}K@{NZpYM;U*7ZTis|RB?Lf8mut{Q9U4p}pLSzQXA}ii zgMZAkR51*u+k)L1F4$OAVo#%1_=)ofy%}awv+LzwVk_iFnxJ>vFHy(DmhkP6zCV>M zqsuJuRa))~PUm_PPG*;DV72?h9**c8RGaCzjxg@*B^_iD0xe&&ya>v_aC>z ziiA}}vcSEUNdgjPb?2Eo#86sl4GmwL-0FKQ2obVx{OTYq?{_VN_1Z)5@l{5w+izy) zB@KNJt|{o0{P33^;~tw&Zll=ohi>ee8o%b^`23%Z%jDY<9rasjzz6onhYv}Qp$n+Q z{*?lyy*d-`OD&0hmkWqL0V&du0^P5j5TE-j-BC357oZVB+Zc>{@0a8tPJjj)iNA5} zxCDKkZ{fUF`EDw9$DwRIvj!aA<#%?G{2O5eTIH$MgN7d+48GfSJr4)S&krCx_FjoB zfhMPO+*u!iz=GpGo#GFzwYmPFI-PU$>mRDJ1Fi+SpB?WeFnK|rY9x$Ltb4s_yHO?K z|8$PIqe9RFTUMBQG_%4S4Ee})8LH2C^vfcHY zhl|#AcAO)<`mHp;kRD%i>wU}j)z)P@A;RGX!N#O&T-l)>T}}_;PS4tK+%HujWj6|p z*;5z%*^+9aUCYdCBL?(ez?3{Nq6aWL)8vCe@plSx2Gv|jDVH&8ClOw+-FFA#*6F^l z%w2G=5CSumN=Z%_>`3^cqK!~by0k2 z$0E(hx*lM0;|=s0RS}pAROJQu-D<9jMGb{{HHnyU)L(0*P&aNBbj*$jz8d%)72&&0 zda~^eBz+XOHQdA|;AaipDW!UA%-AQTQHqNZsSdb|j=~R|mprpMbdMRM@R!U$Qz-x!4Vb%Wk@ft)ZwNmsY*v_q$epob!p8F}F<43&_-fVGn~r+`u;H+u?|c_x`=aa=^$~gD!Q_03Mm=pL+YwzW9()f zI=DMaDw~>8QZm}Oh?I&BqrIXeIZ>t6(gB4%d{y!?%vm#t)%t;|T%AO=tRj;Zne(*b zI6rhf$8;S8POH;j9R-!*_(Q5A1d{Zz>m06FH|J7JB}#A}^KfD5p*gKVsG%)1&MVo& zgK>ph3ew5hiRkQPT#RW9mXJardac8L3Am_O-WZn~cpWZxv8ou=d`lK{qOZdt$Ru$a z`9b`kA_o(h`1z8O1InL^vopvKHAg$=U-Qn00nKmNBfPN*0(xeLyuBDepR?szM0d~{UOLzN0FJKai*JU?Vb&#%+Kun! z6KzS#{CI6GVv1-W0W=RS6MqnXB)27^l%qkMu&;jSV;}J=y6DOMDFSsDZ8t$lBQXM$ zS7Dg{hT!GQCoU!5X#r!9KWdzTUfZ)I{jtFM{=r+y?OkKJetzhZ{eAW{W1VukhJ4Bt z0d`&j>bQAGxTA?GOxTj38utuEP||0YaB4)rR~IjTy=XHpdNY#qa4T#5eF3i@kc`2GeJ=pkeAb`H(Br(CGv@a zi$w#girWEi*`b$$w?)Y4w=UJf1`udNCxDI46jq81rTKo_D>mk>iY|{_WTRE-2g-;F zp0q@%g1h5M#={&{+yCGyX-~F9nBz3Cx5Gkd{MyZXdeSMKT~(RMY#`PT6y+Q)*JlC* z(xx(Ja&w=S4Oih4CK}ZcA=0ogE-3~aCpvCv6kg!kZ}NKV4qm>z>O^N0-apV7<2> z1c8QHm`zRk5-!Kr_FVl_d44+)f$_S}ckx1hQ5AC;p9lhW1im%m|4(^=z~=-)AL?P`=s^yn*IQ{pWOw08`}+= zI7$uQLtyll92h|VpZf0r@H?P>hbf=+DumCeuB{1-w#TQKzDEeko^9)Y-Tg4~+`GD4 z_ZlAquf$#*qW={{4!kx z2cc^PEH~fD25}LR|F6U`NV_suKpnDqEYCD;8_#hSRKg1L@Fwk9qI38CgGtEncd|0X z%Ow1|{W1nYX2&6?D7z*H)2S9j`UbJX z2g9q;lh7PT8B0hx6?m0Kj}(PnW%?2KE=gOCwQ@4P-;TSRr1>BP@3mV>X_ru60GdJZ`k)D?&1?Nbe(UkC{FV#IBH$C%Z8O=yL25TaaTvH;RS+&CYzkQ61*m$;dHGr)!@7b)** zj&U;GVr4dymrFRvEzXrVJ+YH%!7aR~f;n;%{W1E0y!B%7c4cP|HV<%SAZfjogv}ro zZgu0s|BG8 zDz64w&BN+rTNZt2w^CXyYIXGJ6=%eD!Rf}B1md=wbxfWzQbKac_81#A6=D?C;BF+h zHBBdaD&-wh)hcoeNG231v2tBputxM^qOka#16<`NVj8&1ncadEZVZ4fP;hZoMk6^( zjH;V5unJuj(kz`=K*fOYx`|UIM0-jl9BIxKME*&pijE5CWYp@kLM*r0GGjvfA_fr? z$;F_*j4c$E+(iyfO`S`5ak8d-1E>9X<(0fJDvz z)*H3w=LMGG`|q~9zg8Z7hw)zm&i{q)gmxOu%`bob(@tI>ZTCq(56GDAXuCK*BsP2) zGVFi!9Y-^~&PvuS>;Eqns+j`<#ppl8VDzJ1Z~L3P#``~^8#>)0e;ktdqSS4kk@yDv zbARFJJM+B#omBVH&~}$N|0)ANn(}h1c?9MC?^@kIroOL$K=)}-W+CGM+R!!j?MUdM z!*?D>{|LDC@i(WDhvN?Z4nxs!XBq@%-e0@^Q#Aeg-Ttl@pCB#^pn_P--|KvTBLoQ= z#Q+p)cqi$-LaW`@zTGr*9u8v`dioa*HQ3Y0e_A8yo0t}O9Jc`#C^PLS8VYrC3-*H^ z+uR@KZc=+}x%-a(s;A}AIpWQ1C%cYBzX?WbY0~0L6C~fAF1bTn>P0K^hA*}!ws6RV z4ROat&qs|zM+KYZ7d~OGpScmtL`$fm;`{DRpY>QMKWEAXzG~~sDDwRH^v>IR=dZ}< zxW}psuIL=5WQ~&GivL?at*@1D@EPpsKkYiZco7$0b6kxO<1XW)c0)_;V^^k)%gDiE zkAJFvphm_ivuSV1d`ZUF6V4H3I+$`?CQ->%0ksS&N#tBc*GjASRf7Hn%VZgpZ#1cP zTJ+vTmZIYaE7>!+!4%stl%aLape$0MD+UXW!;%j=+!G{Y6b@YxYd%ATzf`r(T^@8i zOPS#=S!Tww&r|-vhCyt6VKK1ELu*fjA&?txN;*+?B8j zmg2UWu20msH0wVD= zQx3EA>kL#ycnO^ynj4%v0E=ZP($2>gO?*AFi_ALf_XUB5x+c6doDY%)$Ns#H7)Df? zs4aMsdz6nzgTG8!@=hr3xP^rl2JKh*!Hi39rxrRQHt03=Kf576w+zgl2iD&f5E2`= z2ghjw+NkKxDd$gmG8O&4g<|33qXwx|tnIMXZ}G|32vfnBZE*jLfy1EatEb9yAcJ0T z=SbQ}e&EHfCW-Q40A$ybabWK+!T855mhu=;DF)Lh9P0p@gke=p&UR|$IS!Osqvq<^ zNQ@wjWmNCU4X*wsP1D%t+M$wih93pT;Y~y;SH7p|aBw-yl#(y)2%7kn+44kEt;wdB z>r9p}?Bs;V1+cWKY_=!}KCqKX->5{sGTr~?-jf$eX%s-R|7t{LcWEbYRc$UWm%{U|#x!7Gy*#jQwBYb#mg~Hy^o$`Bp~36p z6U2s{e=Q4+V#m&XX@mbEH5zg$o zTv-lRZZC<8q|YQA_7R40>uvP>A{hz8w6AK@d;tp#Z^Wy2Q=FnOfJg0F71HDs>;54H z8ZW=+MMlPj@6PTGiz?d}I2p&FmyF{{$cF>YK0Rb5qE>q2&h8kDmx z+suP95A6{X7)R&ov~)e&=OwOdQ66!e7+>1&5SN0HrDe)6ZrC&DrCw`=tTXxQvuO(_ zk7|{2^AvkH2<8+Jmd>~ffG8~jiWvySk>J3hMS*LGRw^WyDQN+djefwUxsP3Q#Jy2aTT-xOZ0unp&HzQy7R^ zZ*CF*x$X1=CFO!S#L!fwqi`|SFYu=J&_a)+OlkDD*o;kMAil_laZ6G%w=rOf%)Y^61=riHEXRKOJ|wTf+- zgJ0%S@XFlQr1lLKOv;)MJ2TihM8@Y?*cLbVs7%i3@>2D*`f1Z?KUGTxiF4NAQehEn zniZLVWsK)2^*@6AqsV6xqWW_X4e>!8C|tL?5x_R02odlGq8b58dvj){;y8$EikH|I z?_aJXuIzlA)~{1P|J*%ydVCuRxNR-h9)9Mp{|7Zq3jXm!-G8|;*e8D@FNar*HqEz0 zk{7^7%=9bl=goRvA;R6W$$tusXS$Vk`_U%;MxgKZCB3Uo5c*>nw9V&Vu=M{%3%QVh zxa4zX@6zyz_ayq*nmH8k=%V?wYB7BmXZTk{@b&E_mCo55lsZIM55Mw$BzXGw0Lhv- z;MZU~@dltI-7o~xIat&B#;Hx9A@m3SwG&R3(Bm6fz@LcTNQb9jlp8Y#uRPK_K?)8I zl%&(a&*wj8z3({NKku?1dLzCV!uU>iqs@Sz?+|J|h$8sRy8VFQ0HWZfhZKtM;#Di= z-^^{^e`vEhLeku7_Be5i2ifz}*0XxViTohxbk*vtg=oL)7L0wA{W9HgaR!PaB_5uv zuy3gQ7}(>~D4W7FX^b+4j=IqVdgIZps|xV@e;$>^z)*1_kr(Zs#QZwE6$FT>Df2Kl zL&Rvn;Y-W@RI`8NR~8jcGV#l$MB<_SVd*mRy!+%;uk@nR6wSPY?u&-}qpffDMua}rSI62Y^wB*rInMP8^Y ztlnBGMogx@C6Xr!Y^;>^JJop$EYtlelSb;>93bz!CH+&WGP*%D)Gwjus zRN0mZE3FGU;IM35E%rXMW&l;m-^H>xi3OLYBj8C6HHD0FL$v`TWmQ%9J)Mhm<7vTp zF@KVY_4UO7!_Hf!?h4Xf*W(0a+H|4n98`8$7jqGI-VSU=W{|RxA;W>`bUpJ*oB%RZ zQ&HRU@6(M_o=n1&%yWNTNmi-6UKGArc>HdE)ssgBLt!FC%2CPixjIuz6=(GUcepzHNQsFAw&@BDUpv*k%k~RyjqI7rIP$De;VnWQ zdu=K)%d*T>84*?fuw>>g=}y;~l6Jh4x!~J9JdJXBqO!jZi|u;ts*_bV-}F%TQhuJf zbt2QPBRX{^{_vH^?plMZf?%GS;@Y8AANV2$@`9xpm>t!Hi$na4qXCo9o4~Cid52z z?aom)$0-26xi$86!>y$nyD;83W)Iscj#lm71gW*s{-R=Oq%ne*gsAU{(o^`k+KH5_ zf0;9a9YqOHR)^ugAu+)4E#(*b7b*lD6GfP%8 z7XpkuoiuY$IsUi&?$RrUB^Ouue;@k_1C9=|Tn2_+J|FNnn=keNO)sr}VQoMB zr|^IC_HaLwRL(!?;X{xUbl*GXX5jt_qM`3Iq{(yI(f^>=-1jyQ0H%jqISD`e@A6i! zdu0+EnVx?{zR@in610uL7u9Cn2G*!x7}OK|Ev*gH=Kl-F?$)a M`>ZN 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%0D8jBrqexd#lFz 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�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

pO4x+;H&1<3fpvdODh7x~PSFY^TDvh9brv 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

1~f z!_^TQc2r8;7yUnM&Boq;LhYB*J8dGV3Fi$Se)$HH#mvIY;m^T>-sJJWAs(&-t0mZq zR;fQY50L-9(a}sdg%EST!Nm=NbO5~0J(>MBHd))B>g$4{7JjDjGlegZ2c;J=O@Bl! z`!pNXsfmr7X4=5qqfMP)X_o5jIP$(c=*tqLc7kVz(GkXU{=xXks7XV{;DuoL<@1EN zUwwMj;`}!mzKGA7@EIDoJjkP{@@T_<_9jwg4U9AS7z4q>vxL}1zfN-X;j)byZ;5y6 zkk7(+I7Ns_6oDobD|97_y`BU1CYuu&6w7a@c`;?us8fPGJG3#ik{lh^C$33uM&LG% z@KrCFgIBgR;9Mye;g3WG-Kn+GNz(!Sq4{hYshG^*LhQT@oUh27bf(7};%1L>s(JA3_V^N6jW@V=3hvs15j%d`4seiQfNRU`dwi6f|!T*w`_lFiDlP#vNmxE@j}TMZIqr+?(lS|x$ai=l(}prjCBeyK zYoc%`;;CzH^UIii{4rC=oLk1pFF)304s0mJ2(93P=iRCbEgF3kjf@9s&2fCaUF^~|w#OdqTvUfGtP@+!h&q8#s}YX~;I5`2 z!^=93(Oa}=#ND{tF4Xs4GonBEp zd})7s(Az*{e)*3?|8$;Al0N5W)=axL{`K0);xN@auIvCK(1$6Hpx?$rJx5q^-|rQM z%U(*t8=ITjZ3^3#Uep}g&v&S(9#%%T#}9AK=I|tQ-URNFOip&I?Q?Qx_w50NT9FhbU(g|T)=wL(l=O%c%F#bZh zN>0b91c2X*tLX6B9|z?PT8+6t_ixT37RBeEIvX-=E>vmfj!TPjVJ* z^w^tw4?9tZ<-ATe_`mvi9p*6Rm%MR^xXh6d6u!sGTDWk~%a(YGfY~1X6^(83mem_0 zM3z|heU1xIH<+Vv2+tM5d|o?-4jXa~JCur-B$4{PG2P1e?ykz^n)k9qA~1IxRpBF`PW)8nrN%i$tant8ocW+>YG#R~ z(?>s11NXDcK_a^Q9=&uRe4+X_pmQ~No*NJ)cG1g;CJhKi9YVl`=mPGG`<5Q<|C~W{MRw_3$h!m-s z<12f4Bh=?Pox;@95%mU+Sbf!?>!)=*nYq$-4cHD)2**aYdZewR_}KP!Djf$6xq(7` zjQl|#QckY7(Lw8&VpQ)cIByQh>*BmxuO%MOnC^aSQBBcXcy4c(Z`e{1~HfWTCpHdu9E*f zm^q9vwLf`q^9FaPT5bu`2tLv)1iTASO@AAJjlSIOAFz2(*MXjl3qXpQ;|fPTu?(%V z>p19;;R~`-As$_rz!C;yAEx69Bh7O2G8Xy~x7!IyV~QEo)tm$S@Vi>Khj_4Lk(8yl za%2v0=|O@ruXkK%l)hfE@IworRqq~gS`Ld`^MGxVLbPzmQ(HhC7b1+GRYXVe(ouKZ zSD&G5;_1OpkO2_Qyew)DR0QJ!NUG@EIu_WCE~Dc9tpD}hdxruUVRigKeTy@R!VAZ2 z@iFC6(DFZ80JoS87MWF zY>2~J)1LXp&zJ4vqc}oS;W7_St>Mn<`fY2K ziETToBsU^nd&#rkWH)pC&Bh>9Vd-IWri#3Hj zt?z?lef~G=7~?vz9zmAC8a!Iup_+c5PCE_KdF_RJ3--(0G;H|;cP(2E3n2`KI?kx^ z?MMv(Ur=xOw1Lih-?Z7RG0k=&>!Us6cq1-KN_@kFE zx3jmS0|V){_#znER@puLCmDshe8c19l(U60e;*iqmtpE6O&-&~6Z(EaH%r>X;Oo}5 z(icB~^ILU%?FNm_C#vrpvF(hZC;s*xdlEmv-GXfJB%oh96uxt|^$${nUc21~w0#>e z55(u0SFrEP`f7~U-05KDq;OU7+|F2uQZCgS|5cUeX|hv+fBV+qz2-E*GKC@HS--?% z$m!!H;6)!G0V$ymGGH|8TTu;xW?_+uSilbRq_4;j|GhC*j@RorDE0qhZu-w9Ly3P< z!|!pwjmH;W$m`LAGyEA()mqUqM zR@h#RctoCzoqCD(m7D#>%ljFHV1w}%FWU)2kINrHTwLCXUmsR)O=~XxE`;d*+Spvi zx*Z?8C^)9D6ud3}-0|5e9Hd3Jc@zom9y|qKH;Azf$(ij*BGhI7Fkr7Ay=X#?vWQ*X zZ6?*zMbg&Nh-BGiw=(cZ_2Al3CA|>FaL)+yY~J_vdi*{d^@!gzmpwBH5xq*Rw@H(U zy007m##KUN@JnXdcFBEZuZ=G_Ha8&G3qJ@{kmarwkX+}CqSQ>&1e>H|6Lh-R;Y-A> zHcp|t{BgLqUQ|a4V}Q%7w(8io@TB(Jnx8$YHj(DtNM&@5zBcLSemM$F=y_&-^=%OA zo<=rt4^D>k2RNW|8_JlLlHMP@57bUldVk*OVrqU0D&K`pz?y}nVq4)+;{ut0BOrL7 zwB*PgAI|Azyx(LE(`6=WbLRXoy@$qp;=5 z+vSQtOjM*md-x|GoQeJl=E4dwjIXa9E1UT~yAzQ~43XW4N*|&R@PR#|?=i6HN=dD& zu#s(%!hRuj-L$S~6azcq65-V4G`zz-;sa^kcZj|*$OIn0p-G_D)64&Qj*^Pk=sJNf z3HP@$WC~y^&o8Zl*~Uh*!z9WBFZTgp`&ZyCH_XE>9;1l@z!Z+yL?+45O~nQ@#pYTr z3(eB1u9)bLD6F6m>QCjq-~{kS7WnDHLouJfLd;~QrU7`){ALVy;0SAX^rkpPAxJBP zxfb@3K);!zB^)>rueb>N z%yoxR$sl+kk~zGfD7fBEG|f-g+9so6Yd} zj@y!<8tf}reo2zyGRQD1YfTjR=_57b32`?fYMMe@CVooS0$p-z_%uuexHL+7RBqPX z2%Kh+s-(4ux>g{VK-r-HiYy%qWHtinv$N3OF`il>FgQjo#Y7z{$lXuA&GH?-{4C}I z5a6IO2VU4ZJ|3=&=;(Aj78>#Ba1(Q;(|)*#a}LK4q2Z%r$=+G%;NnK~MD)h6AmgUl z2~<`7lq~(xQ!=Izn>acHWyDOjqUWjy`inO+O%E+pL1g<<{Ie$79+9J8&CD^UXJ)(V zpB#-{np+Wt9t56AV{DW6_WWx*6D1o*E#^Dd_7tv`7&XYw^we>*?WDP~bBm|RUMLIK zzRC3%ZKr`Y4MFa{%|2(PxM7#z-v^QR%PKRx483!I{Jtz<`gzr^H^-MrA<)1m1GsQi z0!7rkR$grrZT!SmfZoyDDVl(uB9r>R2Qz<)GiUa+nnmAQ&g1jy5hk)XeaSIc^?t5A znI%%}w*O_khOGZwm(%2qmUxVz4nQd2GD(&+y*gWMpcL59h$$}Dk3WVl!jN~A)4l68 z{=IGA&?-pv;5R{LP906tVHTV%eG69ZcHn*#sv|elcR8gL?Ev&|ik}WIP?;D}Y&m|O zsUwPu&3XJsBgz=z^&-`8;L_&(a(CQ*Hv7%+@jP$M&OUi3NK=ANzVq^d*TDO`{fK`$ z=;8Ot!WnS*Ur_v;wl^@OUQ|%RcdP#&nT{IpNx1KnF$Y22uZ1Bi{Z4-n!gYPg0l3pX zZMnFJ%g$*#U+mZW-)-ey(^>^0QrO;Iw!Ex)go@0cAyLta(mI!p43!O4uoH&c%hI|1 zQB*G@fU7a;MEfCUXWWfDtH>6Q{Uumu@?aJ6nYUDSa)sgJik6%kcslumr>y7QnLOEv zYv`$|)9A98fv4GQwoFcr>q_zMNbJgno=el~kv7wlkf8tF&KmFx1JM4oMLDcSG7flZ z&5G*Ziu0xpk>0RKqYWVR!);>KZBv?lY8e)I>%4cND&3hCS;*l~g1>n@!`PnIb@e(s zdXT_%b1Zl zXz;7oi|ul!(+p=_#;A~%ZtIkaU+*R<)gid1yu4R+i*VdcZE3%NE2Cxpv%Ukyr*8t~ zu`@;0E2JdNY|JX$m@HNRP1&)45AB0f$1XN{*M;7GDShQjqN^v^xA44X03>R7$z1gv zHf3h|rQ?#XE>mv>8f0eNI^$$qr_!;dPh>{4zmXnJRB3B9lVFmWxfn!>Za_^kA~vUpsAO#i({qnSv1cv7j80aS(o>+EVPN_ z5t3SYw92+->_wzB+-PuJj^5UbU_vUd`hf7bCEqqR7wOd)*;L6o0Gdfb4>e~1C?Far zkXmx`(6f8};V^5!rDqn_rNv7`~&M`t@C(b zE9bru!CJzNG^9_BO0o??L14w%bL+^5>+A5;QIP$H6}le^Iho3;_OkqQTCZ-3EfZRY zR9{=Y+TjU*2;%L(zf&a9=L~63K3p#+)!H%=9nZ?N zK#u}ZGt=PFbO(gfa8cCL1Z`7ae@1SwlBK?qkaL?{J-(nJ>?OVy< zWQ2uJ>A3Jh;|Aa0ywc7GnbFObSejzB6~d0e9@qcVR!(MY}rpes^*B*@2M0a`6d z)j?X3&E-u|S9vPx)Xlg3qz6!sMq9?`(#<~tsnNI*NZ@$!tiJ>#?+P;$qfw(t33k^L z079(pb4SMe$Jqu)wdXmPM@vAWfR0kSj`TS)#=Fowsm@9bbNM5rKu%r@b*N+xF?Fa1 z?4=|QK#1x%mWtFe!`aT$o@0MF@2y)D`b34dN58I2U>XL9gWX3LTf{7Ea`7}&{_ zt_T)TcOldq#6`${j?wVP>xY^8h7;M1_3aT8?KOEK5iZVmJH{bdp(YcTslnp4w6yBynA z&W6K2EV~`&rP^YjxOgq z<5Yh4RDgNloff%_P6(Ae;Ec-u^x5I1^S{D#)<5An@m_=b?|IvJlCXa|_E(QQ0nxob zmz@2FTh(g@hNAb3ee_mRf4q4y`K8#rxN9?^KY6rjwotkALJ^M5IPk;_>t?V|*S?q)zzm(?J*3=vM zN!}gga%CKE)c-@+TL-lnzEPqfI0Sc!1efCO1efBFQVNvd4h4!93GVK$g%T)GXmOVS zMO%tnixw}%EnI%P_wL=@yL)%$o5_56|NZ97dCqg*bC?8jX>ATg-1y8F%(N!OpKY4j zNr&jz{*WYb++i=-0?m$ae?#DUO_Gbm%PA{YAbF$de4SqzZH@B~l1>ol{^=u;Qja!C zy<(Zz$U&oFW|qT?Ro03Qs}vZ%2bLGMA~FeT5P2pHdHAUwzMCcF5B-E7b-FJXM^XR` z4VulPv!~{b_8hV78WC^kNd@hPgv*z_=;ne-8{7&b;)ROVqtIguWMG6}{+w zRm|V(g7$I{V+AWjZVfG4cSuAX-3qH6TCT2cW zyep3Qk1&Fcx>90wJoS88${NbS1P}3E|K!pGH2YrB(8JD-nh~@6iMTH`mJ4V?(OEOp zDV8Yu2ObwIoXzJatd5BLn=2wRUlCkNM>wUC{9 zOw;?he?biQi~VO66(eO!zM5pS;JmYnw6Hk#Ou-Ly%+&;Q@)8=9R;CF)&~Rh?zgB%l z?^9;Sso5!s9bcy9>};Ky*+3`KY!f2XyMDJ*X}tJ%sAZ^-sFK8;q0pB9XX{h(-KQqs zkl&`Y$DT_oMIN@ao>?hFTOL+4VQD}C7YZlkSxCkiaqb8wsbC`$p>~zhBwmT!`x@Ol zZLOIGHVxfe?PlomvYn(l&fBr3?-JrW0*OfDj)m0)x@gYL>D+G@Nd0&0%FiFR48&g! z_?)l0H7HR@M4449s$|A+qAkSlV<`j5?KB9;{FyzKZDKy!^@>uQ@YSn5kdVp))N%Y< z1J-nnO-C20TV4}GN_+fXSCy{+tZ6beoXw2^H_ga0&QXLWhAJy0;Yvo9(2{~k$Vg%w zR*nW**M}KJqof0GJLr!oyZ8P?Gt^txg)xMEDlzUUgA1MVB+%MZRXsNpWR2h=Qeq@x z1j${r``z3q$J*6rsBFk-J+wf+*l(^eg%#3I`(M0v{w^X~`}N|msGEfTZuRlz6nh=z zUT+b2?h0+|a6SH3>}xyOF*_v=g`CXEZxf7J&Su=&{}=TAFK~IVy|dxb-R5`y@Wfsp z|J?u1etZvj1oZj>?wR1jfI7iP`YPbBkU$n*a@0}|AQ1G62yib3U&r|SB+SnPQ1K^S zj}sw&Pw<`mgyoNpJ+PYpAp3uZ$p3lk*F}56?2Da^Q}@CrkYC6C%K+yuA1NswJ^@}6 zbzh;x9~b{`Xf75ap$bm(H!M8!9!-B^nsh}^g|zht?i-;k4ki&-j7#UDM_6QsXo3dhBvB#t^ z@T5wgkYM110;1HDXnjl*?-C;pq8PjH+?GY2_IZ_OUQK(Kz_4)*d3X*6BCUCTdE(Me z$)%{a2jw2DL;Qt(Oy;PfHGEb zvjiQS2ay_k89k=CQ|yf`df>3h4q!&i*hvpr-W!fe3r5JSnH`_3rjNI;pL>p)exfw! zh!56srIW($MkF+02zlis3iV?61h47e*5c9wQewD8;zAYaCq(50N5zxn=sJci?A>!a z|I;Gl?xj z)|9VcF#+xHy<1wJF6F=YTKV*q+JlQ4gYAfv?N_;jo!Np+$G~wbv?k9O#^Ya0m}Ukb zJUF!r!3Y`5n=kqpB*H;#l2aL_8TFOokOhAhr;bi!Vv-x7^{Olg7k`6KH zw2U--1YR4dMY2TzftwgLxXLcishOj|yiI2UU!&`U4P4)LEL!XP4_ab;#>7-$P+ge8 zj0xrOqz;ED7JabS)&urezzipvOw0Tq;=|8rE(ZZw5J$?7&gsMuoJAlrb|I<>MfCw= z7o?8a{SPNdQ71tJGv`~G32g-iDWxWwkZhOb*@q}nkn*!cK*5FAjX!9_uwD}DYd3xW zPSnwZtyt}sI_7#^ZiF+IDVBOF%dfmF~sQxZ3Fq^9eWc9u+j zZ9$6k=)AX~9P@+|KrZFs?ZCf;a5VtKuUU&!{K#UTI)Du3UtIX|z~}!3-YWjKQ1~yXiqji%J!^r2;{Q4T zpuEQ)#a^NwU?}m-C+Xto-wD@~R8b%QA1+MmXIOp4M^j8mNnK3&WWweRU85iovJ*b3 z`wO#pzgA9e33xlHFOTYLK_x#$1|3d5wR%-SXGDsxusVGk=C+>pyYZzxH-#p&`Yg=# zYk89z^#jZ4Z30MuQAq{H1o&eZYl7kJ^_@HpM^)8M-!f5trOyI@29J%sv^-gSeuNwY zNG;Vv0oh>ZEu|OOyr3Oo^S5$FMc|^J8Nk3 zM9$;e)1iHBBw-c>kSx4z_>^G?nel+n#_nDWN?0V zsDo!P#3BlS3p5KuKm_i$1P7i@%Ys_WIW;|In_PN#l_(F;4-5zsS6Bgj{><;IE_f3y z_aMxtE6?|^HbyC|dRghg0Add?j@}C=bnLHyU@iE;d5q9T!z6qFB&@hDLnS_Qg-3g& zV?(rYpi#8Ff21|(6bn;AAMga&Rbbdph1NCPdf(ed@FLA?OH6*Lr-~?aKL;{LY2jJ{Vu6>UM#8mMdL-0#U|fUjozq(S@gJ6W39XF8S7@}PHk$4^3IJ<@ zq(*bfFbB*{nFSJ&L^u#?J*|e;rg@fQd%cynx)kn&y~&$HBd9}6&vqOjx?-kul)2Ms zhd(u$R*w;dgP=r!#^BXYi7}N$m0G3Gsu_ipaei<(6sx0~M6HV-L{E8wKB2ioHziNa z!l5`KJFDRq_sA1dUkOPSkxI9(UoCEQLe5UzmeztNig|OX7+i7yvu{`NbBnaLbGr;R zfQh&R9Hs?z-Iubj>t@~^WWqmHJJYxow{Q`9cS#)0pWLr_S!YzbnV#_Tug49%YY#Ya zZn@Zhs*f_w6o7ToI8SI|7?47xa0=^-Ba+Xqz=-mvB>&fdtk^?KRPaMcUldmbk$iCD zva4^%v7$1FX_$)90tnZU0fj|JbYdN&8%zv00quP3EKN&PBAH%mwV>(KPYbCEKZ^@N zdlM{oQ!2!nfo8z=VIW)jqtGAXB_raTUT#UP7RF$|CN`@H&k@=1cfn}D97i9GSIVm(XwTKa8e}r8bbWQjEa+eIWy@6YMrQr{`^m`78Af^WF248O zd;x1+5A07V$2VtZh$HvcQ~xg){Yy4_qUdk?tp5;Nj9;eF zAO7=?JiDB;!PC#;bm6k^5a59+`&P2W!s1x&QP9sPL*9Z<`~AP6CqTTN3YtX)Xnr4} zhK=)(c6t0#KCHRzsx*Hn*!qGic&=QZt%VEcCgYm;k;AQiJ)L6|;Js=jN-6Jqq7c%y zY9`yWqT8{`iRf2WJl90YjJ)yE2En6pUhcl=Vf~0}y-$hyWH=K%HDKmDgNmnU2{H3{ z`2EwC)n!We_B=sZ#JKsT?f8vQWK6f&i5A$P)c!6oB*t>vImFOEF9Kkzm_*|OqS1XT zQjc@B6vsa9wxVNHPCQ%t`s`kq(5w2WRaM1EykqtJ;Y5DT=Pn42TI?h)9ImgKMOc+t z>k#xuwEH}ehgEpIrnL}$rlhPY_(D1-JqA3wh_G>(1cMPVKMDvi1@Y5kyCqkX9){4H zT^4EBtRXIMpcF&|vTX2z&>byW3{tz$lLaLfP6cu)Ev?uhaqo^#PPDj!(H_&}q}6uP zYcld|#x<_5Z8u{RFa^0tq;~grFBZGyhPophlsbLGgV0&2h1kXE$Wc*Pu&Nu@2Ope@? zmo|lHhiT@mitCTaDMo>q(TQ1z$f!XYG!>M}c%DAN+GRHnQt~}A_!YV%9UzLLu@5f2 z$N>wr>B4HMTa2x?V1yMw=*&z@L^l+ucSH=c$vV&w)kMY=;Rvz``fH60a8~C>eJhe} zu6&qIY18(XDUYJ8{PgkE>E#P0s8U1l8zMa{1#oOB5UjSvWVM8Alh;!W&loYbPcF1L z9$lzlMmB%#H5_AznQEE2J?shzzPud3M~AKKh$T9-)%76}+uKRuK}A00Bh+R^r2ohZ z2MgFL3ff~g>U4!7a@>{d%OAJ4Q1f!?t84h_3g7S)R43CbAi>^CO;_KLK+saq`Ks@N zgmJN4tB?0{Wo7?ElHth)FKLTs-gphbov&?VfDKC&7K!M&6YA0rN`MJ3@ak?`O_0Ct z+dPs;3Q@TFM^V8|8pSsZQ)p)2-F?`W@H#WYV8g$Ds?aSsqlONWnnI$Oq8?DX&JRg<(>lsS6j<X`7qmRkCk__}cFxX->b6mEYgo z{;QPwvx@g;m4Bu6E|;L#tK)yg5C5A0@ZV;2RAz;GNo4WM;0#be=ZUseU%r#!@KbvE z#;XSzyprLeSH|^I48eQyCbcJzvUX>eV;sZ^IjUO)mI>%*t4xyu`OR*|JzEDmGEsYq zo`l#OHd%@}P^bdT(%`9qM-#i0jZ7Wtsgv)B4SB~d493RX&b-H!;)&)^qYSw%sgp@( zQIxHq3eFKLut}M?w(5&NIiOY~yL#ATjEtZmLnlr6Im(wB?pTFV(ccRwJB5kZb?(6TP3Cuqe9pl;N0_Z!8WZVLx zLcV`Fa0bG7te}o3+{VQ== z3m3Hk>GG8d4j5pH5%gjWVxJn>F^x$m+5vfG7yi|ZzQ9ar`^S~Wv>DU=;;F>Kk8f=9 zE^$(xLx@UP4POnbTM%r}fHz{IXWF&0zSCU{@r>wb$+0z{pbOl~o-^rO9B6({ZT;rB z{bBhWz|J2Nr01I_2VVkK^6-tz&MU5Pf60P2H2 z2Z)oU6Hzl39fknqrKi-SQ+<;2GqAoLzBXyU09--9E(Eco1OXE%4R1dIp&Dl6C z=O@ovd-amqlx(3n%-y$r{!{K!vZIsS&YDbLl>EP&^YSx()IYU3L1d{ZcXZQAG>!xN z=A~qk*7(N0ik_8Aao}6VG9FS|>)PwtuF#m&0SsK(q0duC?S%zEi3~{cVY-!(;t*uw z?EdJ~#6P6vq;fb}e#yf84M9`FV>Uh-x8)x%Q0@ZXh##=SGP z!#Q;|5q#|Fje22k@BWxqpU>avllK6!%$q)Gi8-A)e%|C?V^VkF)>0j)^>{zv_%DaMEFxm)*N)4T2QTeYjG%b?LyrQL(*b4U9fwz>AE zX7iANSHm8(Z{R6J&6T9;5LS^FES|(t+kS-*lTu)$04JG(0zYQ@)JU<~_XvQ<)ugkr zi5>7&s)&82qh{u>tYM}F33hY8dZz8Rh3da8t4Yc`Qf8BqNKQkXwv!IO&wB_#YeBbq z?b*7^i^YMINHZ17IE*csWnSbIDJNHow~qaBn1Nd9hNHqW`fAY8l-Ycitd0(?0`frHp28E8r%NU0<`S5w@_OER0d5hXZ?%s`yk z{r%60t`p-4Czf{$p}DF&$OpMF8Z#A+v1sMia5&HjX!dDr zaJ5)Jjvyb9>5%9Q3+2Hhe|j0BE&94a3oz8sN=n_fpdU!RF?1V>Q7 zx(dd!@xs(qHRBwua6kt0;oQgvH3}P?)}W<{?J-;Q4!51qeTB6|Jo=q74*#&O69qTE zo^R9wvR!Bx4aXoGr<7Ch=FY%Ndy2)El$Ln_-Lpj#G>Bce_CFrixN&_oD;#=4msAt# zNgCqN3J?vm1K??o4pF5IASTzI0dEDa7^Be*TC==;iqpBS#@5i@rQHu!e(a+9ICawZ zhbPDB8;-cN17PHJgDo6`8~0SK_veL~nD*J()MkEh@`McAHwgtJ826QCirhH7*{M$e z@OlrzDDJ_Rj9+ z4^2LIJ|eU2k8`8*l7iuQw`|*&Zd|Y;^_x!DIbP|PGhd<#>~jV#*?^wv)b7&f;`Fuk zeRJU|DL;N=qzj4I?(Uye4c5j1K71zhJoDK&;6IfOwjZ3G7hg_BA$KnKjG5inHosxz zxztONkWGcPdB633j!{lqZd+$n#IC(uNP1J~;SCswUIkbm6jZ`UQVeNJxiEJhR1JR0 zT(AoIJj^hDkxY;q>LX62UGL|c|32qE>7k6rV$kD#H0pF9a6%dzlg8JB+&_!>G zyvT!i)FyOwhyBX{a_6gL=BRIHLLL1m{l|j~?wxytLDnlL9j%KlRhD#QBqS|0K6$FT z!KVy&9oMy%Vk<=Uy;6>jwPU4suc?CGkgXH1_y; z2yPWT8f=#y)YSamdbd441|8DcQikS^FwCiS)VW2uAqHBduV9q*<48`y=cZ2?C@PcT zq@O<$djeP$6nE(QV;!lG)X|lwevZ3U-&OT_{E%Rs!>-BC(@IP~04@}VLO)q&-70?S z=2czvNVcT+Cp+*#-1JmArGs@T#jcLyQ4^85^=`wL91;NsG(gEI{X&qOavDQ%-QAK z6bW4@33wN^>iY(^PQ$Y_AgB$X!7TQh*2ai{^ZZc*U&0e`0SZb$BiK9z4Cja1$E~)( z(O^nOXfLvhv?d0PA_r0EoHIVc1(57-$7>eEdB9-`zrM$^JNk9}iKr>7yEcj;nN1(S z6`pIaYh=S0fQ*pQg4q1TC((fbws(0x%}-Cegl(TjXE|Q>lWUq zz}aE*o&@6u$H_ZwzaQo_#-E+%bIl3<-m9QX>J)e}YwN2hYd8IInYF>HwjoI4XbM49 zgf^nXu+b5V)uPehFw;mfgZtZ$;ic4$Y^k12cZuz?H(%X+Z{*$TithQ|KxHwDv*c!+lUI4+YZP*r#gbtbb@l%P6Z_wzUT3HQ zkoTTPq1fxe`}*r}()`}n1FZV};?7s{*ZtvYJ%24kk8b5zc4o4F^Zl~zipSB*oLF#0 zd9-xh+ox^5O_Ac<&beH!IT;p^JB7Yqr|$6EEXfIiwpe`18=_+SfIsS31unIoP1nFB zwvxgrVLj7RcjSvgYkGAmM5e0sP7MGBywyHvthuKqk2O+;+U7M5rg+L%SguD~cI3O& z*G2D6S)4P<`?q&=w$e2(o8vIqkbIxra|}9pVezW%{YlY4v-^#YcAd%4PiK!*xRRB8Odc_TD-ETAuXypYh4%8jTnwySzAkD3_7<7@$!;JpfG2OiB|@{# zsq*rEwQ98~**L6PY^@v7N3U#U6Iy|>ho17;m69kpCvcZ$d97#D-I5#?tiGo z_v_bWG5RGox9n)Ow$$@r?ISvR8lhaOpQJaA1ybNrk)no z#__z!gJ_P7C@?9Ri0uchm6sG&@?lQ+uZp%`${l_|hKiH?k?+c_c^`MlG!TF;hJpEe z#{^r1aIn|257wBHGF>za9{AG|RyT$tsT2+P__R8Sz$qjZ;TmrbGZ%Y1M(H81fd01K zE`}5%L4i(n8BE0TPeQ>9>(lE7(U@|GHI_fR5ao&=1jlC)9+SdXsr6P-jI2KA5P>DA zP!;oq25cQwKM59`OtZCxAj3bYX#$&VDr4={R4$ROXh%SDb^ARTnb)AA0{L* z{fHsLHU+(hX!_K)0?%X6wn*xp>iN{WU<mc~(;g$JQ5Jv4X!LxVF?sq~QX_T4qygVjt zW`Zwybz6G>N3LRllh{^_dgO*(`Ni#T;my~hj(;CedmVOriy~iNk(!D}Sy46I*ueYC z1t&QBUeEcwIls!Vlz07cfxlsyL_&)kbKTUU$Kp$h{^0iX_KQ=l}*yJPeK+EMwO)ze_D{pQ&l`PKHc`vCUdS9{<1_OloU zb_ud3-6>Ae;*B|x{PnK^*LCmHdM6Yrb&J~j5DV?KXC|5{0Q4h=GtqGkGd2w~jWsrZ z88_ss^@n+sU)$Y2-Jhc9^5~s&OUd9t0N_J*67NKGr^ms}UC6=KIjY`tmoacHK2Ckj zy*}h>G5rL!S-Sk@*LLbhR>_N*hDWiI>^bO@hXnZjzJHLP%FgShXiZ3n|G&R4xNjZ= zE?TZ#F3!Ah&$a*Up1zQf`zrUQ9H-=ek8c0H4d$;BC#l14`^4-YgU^noHOcRnyw8@b z)zC5!0c`;XUG@hu}DCwgZQ^#Eu2X<6@tdDbyA9aLoYvyXm?&QQsA* zeU_KwuVNd#pl4#j9pVIQ)E!Psv+Hl6T{@P5+}teTTd)YaG0Onz=#4*oKNOfHLFo{u z`A_I%j#4`hc1D&R@$q!-d@XlW{I|y&o(mT12^}>D9=;v9?MGto?tk)5r-Tj z#51Ge7O08Y8)G@2iFV(kyNwB@9yB++m|2g6I9JAv&nfY{kO>Y1`AXwq z4X5^$m*86k=`Qt$nUvpDP{K?WYgPjKoVV6BVnf|E=ZBa0jnv1+$&({R^FNK0-M^0V z1X|UkdV^wUG^1ctnHL9?m31Y`BOSPA#yLe6=?My4f*vnlCEC#7aD_QxTVY-6&9DJX z(R_=Sw3+bxHW)%bDNqY_pM4^@H3z&#Z={UJdpp@D6^>~Biyw~?v+^bT``F}b|GBa5 zsZJr}@lm)_sSE17G9zhUJma&x$DTwsnnkPu!BcKlh9Gq!23b`$;-0y+{vvG+!ykm| z5mR9hD*~C+;&Qafxxg4n_OwK+=Wiz$?US7mr-enkH;-+8HFFG;Yi_<(t4BKWjE;^I zqMs12PbOM|SxAsnFA}oz9qsv9E1J=N!Dz8($Y*RBFcVu|i98v;1<{oFahg?~u%8a+ zK|Tx*LxeH#YVNm|C1ojMy)W4kyi%CLZrgolnK8P~;lw6UpYSVulsg?ugTiW(z?J|L zbm^MjIi@6*!$2%*bb53bsP?Ht?-wa2G(Nh7reEI_kR*=t3QA#7j)g{wie@cv0P5O- z8_|w7RI7T3UEu+7P-_iHvU;h65##Y%jqSy+rSKO`A*74)oHKI0hs@tL2wCx_zc#Q^ z`>^~_7a)}I?-|@4<~@9JHuY`-(t!~)-#|aO;*9jw6JXXJ3#zPE3F0q6R8-(b&UJZA z9GHE|Ev3h@0vk9H-GI^PHYd(ipe5UjUzW2fQhy9=-D?9V3Ts{<;4DyLG=bHo3DUZW z*}YmHU-{l279qlxMh$rhRfNB@Hf5CeQ$;%U__yOYUKE)cIpvXZaS`x~VR7n-3AgsI zp>*|RmA^nV<0RO>j1d^AwZ5mgd9OA~KM&iD>6)?XULZC6$;1s&7>;SBw>xd*<$nA% z-ybjwZ(y@-u?(VLqDro1YRj958_WGrleV4L@8)XT$rb-ML#tCPs$Sy{ty0U&G6SO% z>dnqiy8@G@rjrTP&m0nj?VJ;@%DKLkO0~7nW>IB*5}sYW`KYLFjvtHu!DCva;v4wG zng1fC*2mLZg{=wC*^td=>t>%`9y~clYVy_vwFN7V0;o0{8Y*FI_)&40d|E+GPFBpZ z)`$G{?I$xs0XI1Lh^hHx6Tso z1!uZ@wR54auG^}XV>kZp+-~&CBfazLYGcu(q%#lla|qsSL=ahHvhX`bk3VDlU39eQ zI8qVkb^ts8lj?wAGj~~q6h-oSA0W>oN%y#5YEYuXZL^yDGuO9QP@ka2ZnL}$R)9Jl zD|1{dXVl=)*@5s2&8y?_Y&Me4KSofiIC)0-pyr_atv#_J`L*jaX#Nr3IF*U$*m|{}PK=feYAS2G zOc#W_bJXK4ly3J7xUA-Q9b2mTDYd$;E22+G5C&RoN6Tn4Zx*JBhSetP!Ra%)gl*WEJi)W2T>-B@*Bj8j zw|~sI>z!j`;yS+m6!a)#;!ePW9z~8wCGF*WAvQ^Rc>XqxIFwp{O*V{Mf9VpWV>1E4 z^Z{@@1t{WS8%m`x!TkezYgzp6Zp}p}c^49?U-wNUDfsG;G|TE~SvnkHs6cxI@Hau< z+QMUC-kH-ExI!4jq{Gmva(FIcmR;{G?Dv-)gUviP;sq!W=G0VMK8V0^?bQ z70v^wX*a)o+vEA+23bl3;KX25i12EuqDkWWP|^bX?V?+km|dk_UBE2Dp5xP_zapQ| zAizcA1{sUOOwp9z&Xt^?j{xz|B#W{jHw{4b=^TO1*1o@f=!;w%bDj$~+2Cl%;4(N77=d4$@0hAHX5d zS0Ilyd0@{G&xXvH6M15dW7&)!E%BhKGr?XFsB?u~7VOnWuoWYWI*sPgvnmWP0*BgUXhzq5^-_)F~O z`x~7+8;AMNCm;i!NKjt|F)r;>!5@ff;{(|4|M3DCn=gF*edkx|@EX5Zu4qU8Vtc=e z`=rKdZos3RJ5wd-@z41&Kh*myS=j5ejx2f8&*Ng_`{TQZjhS^VLC_u9+{50%*p$YV zJr6iS;7|_N`pR?;`c?24Wr<7PQd5G#EQGu+&ShMGphE1N2ebsAigtqJEePZ+f*yAs z-}NtBPyZiKYpn5*-V-D5q5RkKr;zSj)a(R%Bn|~H;dR_d& zmlV5}59uXoa<1apj~8xUr!@$!nM^xFMQRZ@4@$;iM!+nJ@P5ybt!9Ha|-=uQt$_;h`(3s4y!7 zQ^F|KW&=)9(Ygb5ENlXnaUvAs6?n`nb!O+2^hY2nr8bEro}@h8ovJIjH!C5J!t>(+ zVayx9%czp9m5L9GeC`RjcbEj*Z7)eXSH=L6Kv}&Tl>7UBBiuSz(=6_ zcq6Ab3Q}A9*X@;i{AxUh+Q9xlo2&D5VO;Bp;djw8Ciy_r(&!0Q{8?J_zQB1LIfiw; z!%>0*w_a5qCvL?v%Y53>BTG$mY2m+YU@K|`$d>|5KyEZC_5^Y1 z3R@%jp87#2Kax>CCt}^t)$EZ8VQ;&_pXXOo`Vu10+{E&;^sS{>SK)Z-1PRV5V(6@@ z5S(gyrU3vwx(J?4g8EU++pkzYvb9`by`1*mFLt@TdV>&w?ubvCaB6PIAJvE>LJdqC zx)Fh=)(AfCh9@iD+R{O@`Lu_7TAEdX$MD(8hfD*npx+<5y9K2LkAT)Pp&qOKMdPDJSu+9+=jFF&*56l=n(H*$8mo@!Mi{?uRe5JE zKG#vJlEt(&W&%?pPNt}}!wxkKr4zPF*U-UfOG=$mRs14KS#$lY9j-+ywQ9!Vq= zzwZl`=Te8hJ8a(ELD2i;JJD6cy{)ylm#cKeR)@B)TrtT3d*{qRevTn1k@b27-dW>J zL6R|O`R4m*;Zw|L(j(q8uk$*x?2Pt{e?#j}7qbs~gb0sl>!Y)xH%TzT;504(8(J!H z3QmU6hi7*e#>zj83+ovK@`q}iOIi*}#)S{!ilwFQeid_n+o|ce*ghM$>D+u+PMVSP zUB3VB{_Xz=V~o6#z=`0TuIDJ5Ksi*P>rp!`YIb9tt?d0fPI<@T zpf#jwJ45?LNK2dlKVK_au@>jz8KP-&HHaggQ0Ap`Vf3ty7E3w+4A9UlU9IH{F}4ak z9J`fks$TbD%WdQSwqF(37))&)m}Rh{t$_8$4)Lz_OZ^(CC3f`a>d&QTknh5Kulqf7c%fDw|lqj>7Ex9f^t<)x+$OoR3y;DVlsCc)$Axf5eaB1o^ zAy_}!zIj7EEEvn3S9ywnudYK99Ko3sF$vT4YMTg}iOKk8w?NaMKeH0oXE|o=eB?~2 z&YS=w2{rF&tm6hI9pZGL2^DaWcX*Im?JmKmL}3r>Tqr#I?6Z~t=CIP0e@=$&fWTx} z7v{5g@~ZDrK3GU}B)SXk_Fk>FwE$Nv$1Vg}GpHP6E!6Gs;pB5$>&H9W_vBJivF64# ztj~OEJY9^32a&I(P0vUsl3S+kr-J+sCX;bO8r-H`L$`%2SulV8wY>9*JAWzb0_`s} z`pY5ODlqM){D&flh@40VMk(5Qnc|HteKwOYNh$8BB=ekqPGF8X5h%^CkkyxEnMb<1O}O^j z#UN7qT#qEDu^?>B2Vl}W`9eJ=X4!+gHdX;I2LZpttHdLYI`e|ME*4M=WvZJ_>-%M2HWnrkh1pj$IUYz^@AK6D(xi<7;DA^ zT{rirU-;!M7Bhh3W$kmGs zOIPxEhbKh28Gx;ci_}(%u)#sh%oNm9cg*5Q;9K?jNk<}r;MFoI7>Kx^iQwI7*^tnN zH&0;~%~DwEFz)1qW+A@$6hY0_#keR|(lpKI;qQc=92EJ_zXg?p-QAV+>@n?ad&Q32 zAKftSfZ$#uh6>F$W!27h&J;ic!D zaFrWgrc`F=s7PRJ2V;nd^ER*IgtSCSa{tyOYS3@2tt)b6<&5EU)WUPv*qT2(?K?60 z_5xFnZ^wAHup?RGrdg(%SsG&X<9KwKYAm_Of5v?MT*yb(>eYvgz~PI)FOjYvB=+sE zboIxb4aspjyg%4ziebS4%o(?nAK3{Wd=!ughjEEav@Tr^ivlr5PmQqS83Z@}>9?~` zirYlq$*7r)+?_KM1;(9a{ zqn{{BhAth}gQeO2I1j=kTP5^v8})l^{e2-qv%~apDW1dPak=B@ zpKxcOCC=fzT$Oe5-YaE7roZHH=G9==I0Z~)X2(vNrHjW=q`8T4pz`>TGZUxV!1P^r z&ch3}suOwEvh}@X=-tjm@V0f(=2;70Y0p7`ok^DM|L^m_IY#1eIj~O@k4@-ak1UG5 zipJD4ok+4jd0Z&I6St2)>lq!C4|-2Jv&8-;R>7Kj*<#U59%X9X<1d3rtQk$ZG0l9m ztiTj@xH%Q%fQCk&)xvpH4vJKaDH)i4jdUh;eJBCS7yCm)$D`%L`NUk&Q+wdO6Ifv|XFSV`$Jbal2#>fJNmyv>@Owdk5wdXQ+t=jy#3yT3$;(2zTg z(5k0>lpV1Zm`jA+fp~-uP}XopYiCE2#oMl1pMr%(#c=!uE8C6x^&QC{wd-WOf_<)SCyH+%&T=rO-5HXrzj!AGYB%3-7#*P#;;M3e&&5vyXqZ>=C#*I3(B zI+nWJ=f&osm(qTheprnl0p0itU~M*BL|EMbl>MT06LX_kX{2v|KHciYBhrjJ4T%3jZ+Ym_UT*{fvbgz{49Km^#my3z zlEiA2a>xD_4jR@cg4gg6>5Aw<&c&;V_M9+ z;dp{=dQC0oN9YQ;%t2{$OMa1NX*0r))#`~33D8!0 zZB%K1Ow|sgzxCvv*D>BJ=;zU!;s7GjcD`)e;-#*3#^j~BFv^;{KQ;b+)oc$cAr^6@ z?MT`1Cq{u68&8L?hF+@;Mohcgj~~Y57)6MvWKwf}SzdxpOlCF}4(j*OY3nB;rI-vI zdIDdXn$m7QukhJ4U;Kik^jP?`+F5e2TP*XstF`qH>xYxGcW3f4Qa1C<8ipD2JAiZZ zQw}s(*TYmP2=jnEQmCY|cE>_Ws_l%QO66ikB+bAM;o1vonBe7G1L%@-a8e;e^FxDRLiG3 zc6xPA|1eYgGX5UwhChAd$cdQM_$h%}epYW;@<>`S@QY})iK(OJAJ2;gbQL&Fd+DsE z2l5wtIKne7KmYqF0?c{+LS9&D1qpOX;N~Qtzpwpso4;*7Pv^YAYd>(i|L&DJgMzgw z@3CBNVNZ`Ef3Xw+FOq86L#qQ@*UCEhNI!g=lJ$(n2nUCxl)l%-vKQu^LY&%8V%e3y zG4f*|gRs&QEX=D}c|hMkOZik5Zup+~8S#_HxLvD6oLNt{`IjN~0G>0>8sKP#qSfxL zIly|blikP*dy_uSAC02lhwQT%N5lc4+c5wuYWMk|7`!W7+7S|^kOk8u;=^~yhuKps zkQyw97AowM+C1yU94H{d z6*~Y2RK&3<5{lSQiDJLF)^;A&4Jk-5o6SI^qKX2fhmb+Rq{7r`K~tZ@!hYfrVhPMN zL3j>W_4f(A0vTKZR;Wge6_G*=t%BvC8D{_L?=5^e6UMG>9n{XOX8}i&s^(Xl7(#9V z?AU^oRHFL)u%*KIIf@@Tvr6^%_u5uQWxlSAxg~{bW)* z1Rchr7yF3{zkqN?t!M<EBO8}im!ub#MbDkO~8LAfQI1N#a7E55?OAE3Q ziA&14o)i+?eL7vM^haJx71VDM9GejrO-pqxyL^>!Xyh0`$n|)GG=K38v2Nn4AQggsRzWm`s#Zq&DeJ)ZjaB3et;=9$6lS&E zTor)=js4@{cX^S{lN)q)ZAG!vV;KWdMWs(ZF3`*&lV(5K9B+B{_vb>-F-L5;1u|r? zsH7DeR#1Ehe#BtM?{WC7jf2K}uGaBOL&2xh` zK0NeA!GV{DmhvmM0a}g22VPT{4{N_tRO4rT;I;#q5L->F@zVZHh1chrw$?pYbJK>k zD~S+*ynMCm=f}xYcPx|n5(|BPb}Ux39~An)#c`=ljkZxRiXq1s8{ML{Y;5@G=D~#Y z{j6O}@SSK?HMh;-eXy5p4?wPop$XSY%(JiAyfQtEeY>!fvE2+)vK^ziNDI?)zxB%X zKF$jF2Pwq|gSXf#EYcOJW_mZ<*Yt!N9R1P zb?ypBTof-0LOXzpVez4r95)LzS_HI2eV0@YyB3K~^Tuc*=Wgd9wa`?6>B|&UwqtG! zC+VoX50qMH_LOT>VRszs4a%Y%XsiMXAyZbEAZ{)_l7!c6JNQ++ZZi$2t;UHh-&HW@ zOy>QtNa9begeu?EMTwWn*e%uzq+tXQcw#k`0Wb$R1lc#rlonCl9M;FkEUXIiA`&B8 zjxB~{2Pr{%MRY$*@c<-S>xb?tnAo^en~@1XROPl86{Ldl5W-{tlbX}FF*SD%lu%jb zl;{B>#e@|NW_*^b$~lsS7NW!XgKE;3e z(OGj)(11zu+j#}7D%yE*dsT{D7le59IVk`KuA%LyIw2$DjNpK?caOYm^_CaG4$pL; z6jaFgl2zrjg`Y;T(JHs-9jXG*ao$p;D@Eamj`Pv&ncW6GyV|;+v~Ve~IN;ijO5Av%_Ft;8?%f zp9Ao5lasen64d3@irJLv(3>)Pk2g+Za=GN`ZHDc@F=ctKZNsc0g+!f7nr&k4uo!6>Eg^q#HEfpcg^ioTowuW>JXF@>t6m!n{D;DZ z&j;uIYd1@B%^iVTCb8^`+4-A$qH@>$^eJ#+!d~`=zb(&imb;V{mb>hFJe~Pzt9Kjt zG^X~5^mOJgkM<3LcbV^dm43B%@4(7I@}4%8&rzH81W#Bnp{_O)nCVH^?G)bCb0;NwwrRRBdKi)-pK6R63+K zVD9z-QQN2yx4%2-FOjK#!evoGsLzJ}D{ro0MRixUdZeeNburR=%7-VB+*??>R{tpe zoMYw6|N3Ie7F!NN$P933TV^|VX*T}c6E}W5LKj?H^&-2VB zfB<#-LE@(f3Q^|`Idpc^E2x(bXFZ0T2|?Ht)^{^o`QM-as4qLK#Rl=twjH=W%-#bG zj_&rPi(m9_<-ar~q&Weh=`hK68I{R!4CTlJ1MwX z!Cr|ZO^%B3Q?aO?LLP_m5+*Oy`winv27+FOmL3nAlK3z_j{~wQz3dQ+ZcAY?LT^2^Q5V=Xp6C4l-49p!^_;Un~u^M!&`?#eoci z)p?!&Y}c3m)loPMsPPI#u>lue0-DJFv_`Emp*mY6VCbU_s8y5F2Z8QET4;KRF{>JM zerpK(1pbuTJ56P?aCg$*E~tj+xZSzJ6Kr6tWOw;xPm4{<6AlKDO-JOPSAdyQ6KZuc z&8rHTOX8CluS74kPj~Jd!)s^Gwq>AAJG?0pgvT3%t=#=LeE`HBR}0)ObWf@k&Lm5u z9mCHvrwJ}nRo~m!MMnzPX&R>ZGRW9whI)DpPJ0Q zP1IHTXUa5*^wcIl#idRyV8Gb6uM?fMjYU~R0TSmjC$uZ3u*NAtxBpQxbY!0g5@yUNl0tyG zz6XfHdFL%5$SJ>@i6Hh?GOiDib>ewVj5im!$q!I>0a5_qA^xLo9ExvA!4p z(3Sn9x|y+9UXBlFT3Yc94mLo6qE5u@b92NjmVj^%Mj`a=l>QIvwY6+nQPSUi3}|vq z<^*es=vuO83RhWT{>ecp-eer912;Rfy@y{fR95$#_42>Wg>kw&|0xT+NADF{u$77Q0% z4IeX@ND^O1CtJh(i$9I6iQir9&85=~ijL@6i6oX^YfU;Bi^E=|C%%?-!}?w=m?TJf-;o zQm~)iRLMVvC8HlEFwU5H@U6f9nyl?p=){M7(GXwrm7wa1lk9vW3g6&YUO~RWqM1uo zD~{BCd5Me_r=;;-%8)wLgp>g`#7DLwfU=HPBg*OjV*$PpL8Cy*lf{;pBe(}<)UBi8 z!*5~+GV&>`cA(C?nmRe(`b0&@M&x9Y89nT zM7KAHyJY4eALpQ7LE4z1_F{HlTv#&A^Q=N#A&bvv7r24G zzj^Oj!PQY{*Pc&d5>i3W(*Ae5&yPHP!E=8u zDK6H{=-K{o^|Sns^7nrphSI7d1a}~t1)ud%%ug`CXGc^=U<*O;!`tBFzhmT2udSD1 zXeGXLF~uaEbtYXm)JNMJhC&K6bDBxTWEWuiWUz7!yLt*5vz02UDujte1EPu=EB^`3 z7S8sY#Fi-(HBw%;g8-4NDgs%Fxs74q&@mj}w za{_rm_`X5Roq@%C7!HBM++)j1w9g}LF!<9zMru8Q-F5Iop;SnB?<8*T@=t?MFM1n!rslZy0m2Gx$91ZRGwZq~jJ3q>kpINa{SJ z(L=_TpVjYon+{z-rd8O#@fBJP)Bh&^t#&HEl+69X)r~o%p(< z$s)W>Oif<}6{49vl!U_U>H3cu7uaev?;fN7ytcHI8DpqGrhp)Rh95SZ#WGDuh2CTK z=VxSU?6(f41a_x&JB zPXGPYNRQrZCbF9{j3Y*owlS_u`&-Bh(ALUEEuDrmqaD3aW*I)~mLR~;%>$?3%}~-Xxd>iLscDBr6PaLws0JPc zH5pZzNZkR78=Zrv1=WE>$LAd&ETO7-9$VS)FV1^D{1^OHRl;K4JNpQTBLbiNC|J`p+rqpfB*g~V(p#94gY@N z_Y1!O=QGs@2TxTUN&xl2c%sJfgO%BM$k#7fJ~_Us?%&O&p10z@tv$eg&byk6TPOea z`~`tzCW;qZC&_z?KCLUOrN9{pm3S3cR7Y6CMZ=YSpWD>hr9WFTM~B|jP;khL(xd~b z=>k$zapjtyVt<{^RhAzUpXc~2>oFr`D;|v(59jr_3;hRK-*SVqmV}jZ|LfGM9{7)M zw_(PKsP4-}549COF5r2*4H>`Pmxkm|`Q#wVBu;#gX_DL9gCTUA6IS~U_>+B|2I7&a zg=$RlT41d17|a+rF|>|=izw`;6j)vNVGs#&+R(kl3`2!{X{BLeV56P=Uc4xK-4+r#jPL48{J@9`C(itr~w}d^Z_dBi>0K?6}4%B@+=I)ysJMcELy%hTCa6|f4D?p z9ElSDeqST?T*8s0VX2Ct3m%br!H-Ju%jT6L3ka7uC5ls!1ShfB9%-S*|_dR(eJP&AQvkPZpnu|+^SNGco}S`Q?#7nFAKekdDqvO zR|TR17IL~T2jhcDOeNQ#aEl}-Es=ch@G^JaD2xG%_mUQkM3J@_v8a`J4>=Bby3v>% zxGfhJPDr0kpqhROi7%Z;`Li=P>*j~}qs1^TJD`}PS-kxb4g6}Q zUx)5(z~F@f!4*dTg}aArU_z)Mp~-*w6cev)guzev6Yq?1|$Nl1De?^P4Vn7(nQf38FW8U5eqUYt0j9!b|sHX{_cwc5=IOYIV^>}48zro z`>v9*NVu#(VP{W6cu$C`2>Mt;h{v$?usU}z)%IE)C6jR}mhJMO%97i2xx%jWC@{$T zIfi6KEz|ROJ5g;D`Weqy4xkqvZ;xU_f=gELl)mqC2Jh6f^*unb-VQMOI z+t7Kqw$GVVU3IR;k~(O^|K-1Y+*UEaMtnITk*WZ-5<`LW;;w=F7_p9bPSv!jjw?+E zA?>2bM9KZdODqKX;yr`!OywRkMp1esj;g#eV7RHJH%OoJ-9c_gWbLCf3{YfVJfA2B zz>Gd)y;SWrXlj`yr3SgoeU|pTwDR*iQ~DLSA9$Jk#kC^4?vI0ZV(@g^z5)D*nAG9J zDfp=G8gCG>+sgfF=Vq{e=in`p59Q|Bsf4#PIjRxZDbzL_I_KcybW<=Gg{s(`KPYhV z1+To>ZU*V|d!OtwZf+*|N`DQ{{&0zV0NnHkdfubF2MbLrjH?^YH#JHrG@*Lq-hgIL z_^725ejC5bx`h4KQ<)Mu9*?)=zo?VVticI9-W|=h{18jlgbK(?-yW34?voGb4gQ~|hI8bxae;F~?iKTjpg zOSB*V?AA}*^2oPQ7BNjbATUybJfz{KIV_aTp8L0nRTu{^$7`Kpe)#i3ZR^J@W93}U zJ!3|h{NvwO50hG$jdpC_RNc7u{KPG1%H>oL^m>`)hMFx*Oze;52pipSI8dLL8jcD! zsi|#aOew}Zk_(I$^-!hlrWxLw%(P(ZRaZdeS9s-oj{cEhWM0P^tx14)UuI;N2*EBR z7g^b7VR%8b-&7ZiZ|k5X)?F8_Oi!3BpN#q|87wR$2pl1UW4lro#bCw>jWmSI<}oNA z6vLW21DBo^ad51T%kzeyHifMU?!KY(TtNK{D^L%qAa)^6az?T+*G6lU^P57iIN!J_VX^-$TS+dRuw6+cNc)|t>@P=h)XoyS{OC_U8kQanpH>O2|Y_ji=?KYcTE%;B03?=lVMlqlQ2{tisw_zNnX@(ZR@1y z)%AcX+>~zhogA*)j9>RENV};1t;TE|m{jjLtso+wot0w@m{_f$v2;_7+aGgO(@1Fc z!@)~<&5+qOuoS>ah(#>MjGryY9x12@m)H3{y_O9C5K_Vvb@ix3;!@aE?GFAZD&#C? z?4Pr~KgvAj@yWQ~&i}Q!aq}ZK_kT7{V*Tn&uO!aW?T=;0m-|wl?AE;G!^+~4_S?cK)mZa}UPvVf*HeD{D zclA#rgHz4V>01wfamxIUNT6~tG#>f{$R-0fhWuZKGvgD_D{;9UfW&l4O zmFc6E6Ut&an4x$GMU^ik`2aafc#|#P@8H{}bF2>0pa<5tIPzTS*2nEG-GuAl&v4h} zTr=&5i7;d_Xw$+&`OL<~RM{ej9^zNWsEo;;wGrya%J8y6@rC`#g8t#GzOEuRRTF^L zDrFTs-x1(x29DWVgJYL~+jD3nO7Ks_4{(ybYQ`?kzI72no25C{7YPz;DltH0Y)X*; zf{ZrE&ehx*sY-b-mP{x8f|uuY0*cXV0NDL0GaN0>3 zD-?yzG)PKV!6B|Gfx7mx?&`?uSP7$f$I{Pl{@u1hz36w+P5+ODLhkh$#wf8hY-T90 zQDN-Mok~IeSj^$nua;W{eq6W_u)glK_X;mH`Kd-ph4ujhKb;(XGie1h(2WdJBW|6- z>myDo6@UPAr}Con3qw;hCklOgx0YnuOh|B@YzOAwI9V?L%cN9IH3MnqD%yg;t)1P2 zpismxDRw&erHt(^3qHHPJ{qNBELJ9}`($X&$<|a|C_BfmCK;oOb%HDC>=oLu1L_CV z#$uoT{0nKYT}`uFzjfpk6$Ixj{%QmC`5WZqM-)_;HiK&b^pRoSFBGVf#}gqIZG?^m zF+;ANDP_8g87vZ4BeoW0!q~E=b6;uWi{+78bJjY(oqev4Tc1oM6q!$^_6kI~go6O! zvSVu|BWjcqWJg9^p?8B^0*gPcpj)RwXkY-ndXBz zsuDIqb|lyzqs1FfCu3bO^TQ1L4``7&Lj{YA#2&~&@f%%vioQ<~y4W_pKf>+R_BdKC z0uUepqyn=*E9a!~)}n9ugh>Y|GAb!Ju)`*qvKyS#v`4h(P5CPz9A2RelYQD@jqT`#ZF+Ua&vq12%^0SGvU0lZ$c4}qP3=18P)09>KrF~2A}Z4~_<*&Y8Kdr|9k zaEDx-?77jpGlviXIAZrlCvBeBn#Vd$Er&_ljwiQnQ`bzn#@B*ue=kjxU(HdrIi=)a z`X8OhKjN_xHHF*rcwf!2%3~+zS0_d2QR33Np#9LYjp8SkPm9(?#FkNk!}Ku5^)V>D z513u&aM)$^bw2%PJW!sm=Xv#Nw!3^u;CcbN;keWNy1>2DXi5ER?7y!?{~16h{&lFC zw;GWy6y6FGaj8Di@2~$5NU`RNiv%sSZn&P%g(dDGwpEVU=Yr2w7`&Pcw=>7Y3Qds<#|%|LBPM|d)dCKTkD$<{QI?My{JHo#e z^6tLXyc_2zAh#eD(;G*3uvu4R?;*@)1wbe=v6|z$OJb5XE>^E@JrfDX~AP$Y2zd`cYKY8U70+Q~>LXTdhtsBxZUNMDNfh z_UM29bIV3=wX^vec?-CmHXKT`8ghP=I}+3use&L$?9v+AoK6C8AjrD#U;J;fcIJzN8Lm=Z#4)1f0K0hc8k0Bq+g$sa&L?N(ww;EPHRY zTh`vmTPUJ=O4FNruKz>?d!PsK0t0a3vF$5-s3m&Iurc_tIk5iHFkSF7E7S9Z&VZC_ z1PETF<4!VgnOJNZG6fSF?qK|rcc%T_8pcWK?TTA+P-ImApsaDXXtDrdms=EDGV(5Z z!FUqX<0jCRi7-t{h_VI#S;u{1U}A3-gARt56FJkuu~0$vS0INKKy0U*<2{JA5vx?a z=PM>}g)&=rRpj?0wppiNzCdqc`#L}jM}8T3SaUvoO?0>6t7T3r;!kia4lsCtmkqc% zNKv{6oju_nV0io^>GR8?nTYYwdxp=F}g|l zU$r=~n00qNksxUzFy(a-6=`5UToY zjiC%q#mo6{k6^3>xwKi34^yerD%?rJzm%X&u(<_O7SD9_xOjM;)OGrHp7c-2yA?Xtho zSmJ^h#u@WKfDu6rN(LI7-RneJELYmUE;f%xlYBMHLvLYWwV`H~UmzvcaZnx)aQz2u zf)l7$?TT-^etE`fBA%r|@La_+M0Zb>4gqf zLkM@zxu9tlTQq~;v!p%jiDhqd`{mNDB9AA_acV8D{;{hXP(Nyq2j*#FdUAqWn>7_I zd9kS-ikZ5wlKWDz{y7xRQf=a*ALQ?THkSLR>@W9{m(RQTs^^#CcK@rr=>H!}Tl&CH zyaT9NGk)*g&yGWyLJkt1KQFAZS%6OqY3Ls6c)m&3n}2;$te1M`_!MpW^*660Z7c$k zjB8to$w2!zF0Z|@Jle$;Z^aSE2HJ5DBZIDwZWN%YLV+EIea%pU-DI_^;mC|q;>hDj zboqt|J>cCALDT5n#@;>bX6;-3=CiA}?+$t8<+aNj7dwG0wd?29I-0I#bF+u~s&_9q z^*;Qf%;O0)D-SnMm2o&2!q*t#6nxhK<9Ft@C zU~ek@E5JHz38mvJL3Ws0)fzPh>-xOh+uAxv9x2A(KC26B%nr14&}%i)M-%8F1x$lH z;3U#bu&!tF_X+gN6087tN$dH)?j$Z~N1LBn#iEN5S~3C*q}+CsxZUlVZ<)C^``UgU z@zPsLs>O>r%jFsssAHH=!HI`!v2$(i@Os>JZE+E*(iycQI_wd7d7`Q0d!mh+ zMMa#ITo!~15@hxrFTq#hjh={tyAc2QThn9>;WsFcOp>x`e-_CTdtNS%=gsRHM5zV)2QYvSdXl~s}MGgJy&C?4J^?QqTJxe&iACEbI84z)a z8x_`wx*D62hCv;T1lcH@DKdXIrd4)iE2H9JIZPtjy&|U@dB?(XP~`8=b~xxq$RTeD z=bQ?gBK8>OjY}*s3Fj}YI7@geGF4()_7U`9oN-#N>;1aP0_(r&D`jCQq)=Uero=q8 zJv?~=$WHG?t1}n=@`sw_fDuS$!Q|&BeMQS`GB33q+7jE^v6^D+)AlG@b?9=sV$lIq z(D#kA#rO2L%iiJ(d=PW1@95QdgYw1*fQ5Jj(GJ`x%q zo}I#@c1#WkA@^gXNODwV|_=R%Gawfi2IT zUj80RR^qc;d*mvewL_;OS-%85HVXo_R{7rZg;y5WSkK`gUaZ^Ayrh$C&F*@(C*9vJ zvOXaKjD;$7*Hx&B-;J(H`yZt};QAaSWiIeqJ;{JF4g@9Im2YrC7&VKm{$Oq3aa-x_U>jFi%}A-J~2F z66k*S6k=S>V`8d;z-kkiKVIY>&i!v%)BlyD1d^F2MtrC)hRzQdcD;GYSx=NxHgBcBmrA@AaM37gg8&3+#_XBalq0Bb);4 z(8gwd*hiW4^VH__^C_6PMDS)mOTY)|apyh}u4b>}KZomA)lKit`^$T8Pn2U{M`4rL z?Sh6NjaG(Aw1wo%z3TcCmyXDcE$;CbABmH|q)2YPHu3gDZ5m&dXyfO?kr8P-}+h zx-?XTNq=&<>)}nR`rYF7c%XQz$vf4Z(5_PyYbNc7-gI#=N>;-9F2s^9-RM@X0!3yK z-`#rB)Ehq8t-+eyXhAGl)&WAtV*OhC+r;q}=6+OqwXlf+vgqMXvL#yck481>~d z82mLyz=jdx3gJ6CE0D)kc7?v48;&i&=r4g~1EXb}AzsjI5w`2&Jd^CaAb0dD^xxi( zK7pti_on7dY{ZzjZm@-yE}FHs`|KMYDEiTtqyP|QxML{xk9dwky9m8z0Jbu9=qE_+ zTr*Qc@<5F#NIOPPzcdL;SBKx)i(KOkdL8Mw9J4JJI8TG;L&Cr*=pBG%nV(XUk8$FJ~k z(6_dtW_Ya%C7MXR#JH%j5+yDf#nqPM@c*!{cdj)){tG44Zw*$n z%1q)cc;z4^NlV_dBd7&jz~HW9Gqclcn#M6qlJoT%J2Qf`2yw77eAV zR}iuv#7fToiI89~ex37CTKQ8&fGl>NhS`LM{`hTxbK!2rR+Mw|eFcT|Fm`g%#v8fD zaJs%sIhjQa#f_dlg!n$~o_AH2;oa5GT{<-zaw3+FQfw#wi;(_*hugVX(yjM6l;s@H zE%oMB=kYzoVdD>!n)2Jhf|-Y2SMnK>S+X^ZeCm*M=ff2biF@_~4kS<_u7%f@Nfy1a z^Y7ZAk3!WHk{qs_fhGS^z7WC|mInVsu^Xjou;@(?(?GYTwY~p5`(wC8)funYl*d4( zdXTblamHHUfeT`oBPaP%s+_1(t8p7G<~z4}qB+QTP)>bvR)o1nIp<=|ba+ z9-F23I9Z+)2}9aG0--Uyk`iJc3I(Nut_=A9*}lrWHWt2!0A}3tIC_u`X>8;l%{uXz zF5{efgv2TZgzTiA@AXSt?H#|1Yt;|DbpqZCL^MlnpQcJ1ASx&dKJw0z`w=gV()Dfn~pbbpCMeD^UfB2$AVnO1l2RCTPMv zXb}l0y#CmVqhQq8j$dXiKS>{i39Tt6B&hmhji8H8qZr@vpfcD3>kh+nV-%FEVc zw@Bd3SBTBK15qKB)NCZCqV{m!&AN2u*96>gofqH9C^r8TGb%3uqkr@<2mu$t6?E2* zPvV%v%*#Je4<+Y~llg)kQv)16WdK>g1mY!Ey`xtPG)7Fx=a1;GL6`__8Sj5B%;88s z4@DLp=LO?dh>Qe?d;xJhwn#=Wg~d>o)l3n|Lz}Vw&4T)%G8QHP)d`Y&)o<5OokBJ~ zW^8u)K8@tozQU%k;u0bvAhgjiOr`d_X`U0K+8)wuRF7@g!}&%;?&N#>0=W;vM- zhB7h2OnMEcPQOQp5$d}K!FiyB(oQFA^`<+j# zyiZ+ngS}2mNzogV*S>z~rp;#LBDBM;%r0r!LcFuca$u-#WEnJ{K@ovdR_aoexqP?r zcUI}^-DC@w-J2=5X%pDj7m`6cJi)4pD@SL?@g*J>2Y0iKS$J5kh);S5YsrTPQMFa( zizpK;Xxn^EAEseKuUmYBgz>NXZ{r5%!;YQ@=C3WT96Db8t?~BMeN;T*ss^?!|KmQ4%BM*{K5A$f96F$cw7om0?QrRD;SJjeHjmZ$@ zWh|9VvHCQjxMz^gL|?lXQiU4zw&$S!-1W!_RX~PpO~H&bnnNv?EkF z{a|YRX<_QN?S!Y35O|^A+Vq+{{oK1_RbE9U%t>b_?eKfs>O|fyUX=E(hPh{FdzX*f z1D)Z_&0F|)|CI|X+;MJ=+=qgC@{=c*_!Z8Bl)Ef7uuZ^u%o9~ubKTp*cc-bZ_}?F{ zZ7TmtxxXgj!#Vw@{0Ok3uOYGy=*WlYY(Mckiq5$@tL1MVGOu#3TRRc|LB^(oP%oyY+o3%)6n@Q4za=|D_fN z`v0`BbuXgbs)ra(tZBTStM6$fetx%yIPW?hJdM=}61-eH?fCn|o=+VE|7|)SGBg}0 zwGELq{bu=Qe#Vsd)Hpqy-wkmOEg_cz;{HY>2xrBVn3lyd`K}vqYXye-$g(w+{`wPy zYqj?;Sh~lMfA?P?=Q~iSa_qs@ZTgbk<4z|9EyaP$O3SqT?5pR~vdjmt9*^}Qx3?=E z!vH7$?&V%PQ^eQYoVj%J^dmdnev;HcH^((G5(|4Rf;idYhTan)#=37*Oz@` zyCU*@U!99TH0P3S*{ERKg5V!4|KUZ2wrEiCm=`iMnt7(GS|J^>`#-0_ZqHY&t&`6; z2b@9viXQ%Cej!QjJM$Z3Tz&Q_A-QIT;}t>+l9zJroN}Qwn>%3=dRw5ExEN zn4(o?QsbqiJs%^7tY-k8;EF2n5;I|LIO46UmhsUy(yORxTN62meODgYb3PE8XwI}{!-KAuJ0dR(%an?ld4h%vR%#m;wjHs+2mpVfI?;z-ri3ae^O zaE$+p3;!}eftK7|rd%5pi4P7BCnVB|=Q9=wx}NP1IXv%M{G}lVqXz+0Hm;?wzvTYF zRoco4+8!bfcx?gVbWLuV&9E5YvfI1r;{MnLxO1$=1XC-#4?b2GO6>FaFy%9b?4Z4} zT|sq1%)KI?gDNZy=j_6`B|$q4!!&56SR9Rbj}>Pg1zBT;o@~ zjY5krs|z#0sBbkh)iL6sHOU2(6he|Iuo{$WD}@9T3c-5v6%j4646rWMi?L}Q4X2W) z#&pWGfxP)Pvt|Etd;e?oDi_+H36d3t6z?L$gTz9f7RGY~&lTdjejdW%s;b=vfSChk zRisFNCUlz$;HCbm@m8se_v^@0*lqINH|52bh3n6!>}) z*}HgQz7lPZsZ$XFU5;j_rB5$C1(3N@7f3wf=41@ketyruzHSS=XvOq5L!WU%sgnHP z$zmfuT*jc$K-PZ=s)*`Ys1E}hfVj0aCs+EGQUBITTjK?P)+05mqMjJ+anz&XnO)zH zr}yeX6-3K~z27^!@}A0OG^b6D;#XX-cQtcUmHe0)X~VPWvoUSt*iq<_p!sK+`|w?% z_sZ1{@;sIG6s@Bk!FS*C&pNLQL^AvWH$4OlJ1c@)*vdq7u{D{CM!kbzNx}G2e#Ypu z<^hdk*GIB&PVv<)>7aid_o?>;d}34u8NBfaabKAD5;Qann+|@f7ikjeZ&!bN+lkxH zhK(rr*~g{sCM)9WAbIGFfSDK)W*-ebxyOP7_KA2jqeaD-ABBC!=`|hr= z6x0%@-rk~cc+DG5;c|E_mhTCghoG*S8( z`{JhHJLALy;9^oO9+d4tdf~jauu%)1I7All@4KxcFXFITuAd9or-2ERUqA3g3I(`1 z^7Wu^#@3pmFgmzjCtwp%WckIVriOY`u3ueE=8OOtGD?*$|6%^|z#|P~U*`3VjKlLR zqL6Mu5soKe{ON(UDN#s9@xt2D`ti}_D&#*gdqNDGL89#f}u#>;ZTnHsMMR2{gSMK=b2%u0fa)th-SC7mh zh1hu>kgZaM;>M$8kZ=(8+AKdu>&Wiw@R$(dw&h!zWY=mSw{&v82_zwiHfpq;gtXx;YG$|!tjy1OJY&NeS+mu+zngK1*A`_=H6@qYQp?`msx ztr*_ba2mOU6bp4|x-iCd$UlK%w(vf<2Z7L+Rd4Zt>!Sem+J~pJQO1lILvLh?yK>2F zNh7*;(%z<|rs@eeXaZbgEjo`8*h;&|Ie z_CAizVeIOKfHQ!_693Pg%m5Ix+>5;JxbNqw2u`i{;g#!JuEfo} zP2i5ykTI4a6~%r&EW7&R@9o)SdZ)*v(7T5_>wB%})S4^re`y!W03#pSk~$8GB~`X{ zmZ^x`%tPA8y7y0i4w`byRCTL^PkNE#s2aH!EcvR~(frkfMjw25=PrR4HU9K!>XK;J z;3+=h;Y-FV{;bLyB>oU%1UL3Gfvl1Kf{E21+C7$Cb+mQ1BHP&{xylzzrXnz&zw`7- zi`?{!e6+eA>y7gXKI+}%c`!K4B(0JkzZu%}LefMT%>TO=V5%S5{n6Jjwe76X;DLW- zT9EW_C(pePho>PyfzJUU{`_r^ujSi)rj!@vlQivop2|fRpVPCp2Br6HCk_^A5n2qP zdMYu{vewGrV+g3>ITJrWH(vz$*U^RvV*6W0SX)R-Ux!rR78<3jppRBotjSi!CW9%L zqlP8uD^WImFEOz)!p;3P!~w}$tP7ZZ)9wo7Prt})V@sc zxZij+t4%Y6T}%~2OWnB2PHCXUQyvZoR^VA=nM3y>fx1dx&wg}k5jF13_!z3zCiebv zds6Z}_#vR2&`dsQKKuPaZ#;hSjiXt&nV_$zd0r{80q2iagHLERB0|0mFWq9WomB_w zB0RA@&?n1>dnMW@u1!V*1`6VIG8jP{JY~XWZ|` z%nH@l(Gwszz+>Vtm!wruhL<L-l;j`l%ZelmCcp3lVgG~#8jc5XLL}Z7gxe-5Hqn)0}d&FduGu1Mh+na z$Sk@OUKff%gn%}br4Ih5)4T(sh5jfk5u&iL>@Za{fwT28g*kaq6G&9#gkVh+kQ$u? zP6drt0M-Z%8g*fh4zX0caI>Xlrx;|aQgoY&o#(5y1q&3$Ad1n_(DUa|y^p3Eu!@~V z?U@-At=*Vn)Pz)R-l?q&!7ro@@gDD9*DW~hcTcrRdv=OGTQ}eRwieh>73{;O9V@~= z@O;Cgw$*E>WVWA4q}=TO2*pMG8<{2K=#@eYt)qvNg`#&KFI!W=3P8Njrtli` zn)llqXE-4@OtW49z~xp7?dU*aAE4aevg~nUlYm$#zg0Gb=o~;p{N)eD`fb@(31Gh! z>+KHtDF4S-Qc_<(5+&bRqa5g4O{R0-5YYp{`h|eP#AFKqiLwP7Ds)}yAKPQ?yNoKY ztHzoBE)Layrbo1iNyl{YC(9qGlPqvT*;ovD-qf24uJ}($2Jdtz+?2 zEL~Ua=XNlO4J2>b-*pt6uJTY=yS{XC-D|xYCjX}Sh$3n3{4;nlzA}ifN(~ zH4{?~tAVab!Gr$)Fm{$fafDm99$;{HcXtMt1O_L;gS$%zuEE_sKp@y)0fM`0aEIVd zkl?O^-Z|gB_xE?Ix~l(mRd-kI+V9$HKkJ{&fk~gU1)BYU>IvH(O+h)H5T;N?i|6|q zgYDP-1rrf)^O(;IJ}{_)9b3+KsN3G*a+bPjjg8l2(&U-CM78_ovsV1WmcUXZ=6@%> zr+8!jPmkoL!Fbg6z*@;`O%K_P?Uh=-^7R<&hrVYg6;f?8% zq$`S$AVW^%UU2jLv@wBJP(F{$s9Ncr#>Plq*|*8u?x({6=(U6h%xSgBDL+d+gdCbe zL&p^}quOGyhb?q_XgA{S!bLfb7R06%2W`&+3n_gwY4Mb z!5>b(-1YoHM~`oozZa5Isr>QEY^UuPJR6;>|CfL*e*h)$bnnNUYPV09zmdkby{AN? zd-2!z$igIjaF}rMlJKFpmJ_wh&N*n!c7IyX^?!`yKDaCsrs0zw{cL|^Hm(Xg`;O_a zU)kc}^zYu0(3C6lZh%TD`*}u3{ji;~Sru{^+U*S)U7`U>;c|+52@Z&*Bc44H7S|zZ zy7(|XhF^EqWK!yX?faYt9sx_TV3p9|ESy7n;s_?kN=jJS@JJ-i5iRMV_#$#79K*> z=!RNb6CXYb8!Y8b4kP&ufGj3ov7}!854en%S^0KOu*PGFfELLuEm)r1wOx05^fr%kekXA zMxlZ{r&)rcCzU@Y(Z+n%n9gX(+(0@?=-Z0`c^=&j*|AO009ff91o`Wf&Nfh{jpvkU zCF$Vo^QD5mF@CV1!(aAIx*pw#F8ZGIP0Qm$ThN@W?NJbc@WS!0q7}`;W?0ZhK@GAm zu~H6>`x&z@^X=iz?~KuhBbtUo^DxirV2c=b3=sPgP8@9uDEI@?hqPomn7P6>L_by4 z8e1GH5Ra<_Y6W>!gdCliH@apSyl(7HPs*8o0npXB?X!jzsrPdybZ`A}HydO%x;1`6 z2x7xoz+@0)J}x=Wu}4(XoW*6(n$)2&PyMX!8}B+R39~i8)qLB?W1mKc^nKqL$uNKw zqeN;6BL~5(j8ET=9yX}VS58%5f=x_qm*V>F$M2MdvN^(gHl#>t)NRcL+vt#P9&<-F zUK$nh%-1Bn-R~D3&g30HSvP;`@RzI`Ysai2Q!PDQ)Fpi1Mm}~;UOpW=Gm4%8r?H12 zKtvOm1O52r(%t9czJgu+(u`gel*`Fw^8D|4dztt$*o_($Kv{(yvCja&o1yXV(gafW zPkrHKsfvN{qCi$fTkT<9PmGn#!tJACg4HiUW+VAUE8LrRwdZl6Pgx&X%Gp9&GEUZC zWpy;)aKQt|>4p}axo>x|LnhD6Abw28E+oapT$66?)%e}Cq5n!QPZ`0mMCHHE>A5}l zdj~DQEv+<7GWO1$Zg+`Gw~|Nf$uHMQ+y0@SE zx@QH(-dc@w-o)Y5q{z^I0FpcCLa@$sC6>hp5djr1v5S_|#@k9kuABIX_`1l8sf27F z?P#XI$W8-G50OcNBKBYIB~3%Fa2{9K!hir;{$rcO?&rXGrl;;e=bNo_F%!R&;-A+4 z?D#jHo@7NH4UXrZn^$~p1#aM4yBtJ^^K`VPojNht`hQZMQz|)1WNUeyeG<9l8K6-y z$0^n{UC1hK$zEhQl-}QAg1b5PXM(qdt0*wNJ-IZ5#RlGDa}bYJiFTL1yas##aNsfq z^X+0N9qK<6Xt{n0iYIKa*)P1~Q2qxnu=z%<)2lpG$?jhhu5pA&9f77v2yca}hGJ)b zIO93N&p-AOv`<}b``(}~|L#SDveP@ZgCR97l+w2!T~b%hP$m>T=d+8mye#=%pI!JL zbR4G35xHONf2|pRIevXPU~PlqS)#7DNHHLM!5a;6_Dpv6W_>skqwKopjO@fT6NFLx zNn?L*Ex_$q)(?7%^j+2UT57}LB>6d~l)}R!CHMMZatMX|W{ZJmL5l#rBn*8=5~?Q_ zUe%^im$Xcp{4&hc^8jNm$77rV@3awx$nWWFK9vG!B&p5j)|2VxF)89r(a@O?l;PNj z*pP~V@$h@V&-77|Y)trZ@E1+gHVQAeBP{mGrbf}zKn3|cOVekRXwr9VxC@lO_2G8X z0LrwrWbla?!$c^zWc}ckhNPunb_Dp)C72TJ{!0RbC;0wdrVTp@;?h@lbvW(mhOi$# zBn*N(cz9wYa7u>)hI0j+b{{nL&NE0dGl_s7)!ZW^wFJnBW!BKc+2B8f%pr!g_5G_u zEHy1q>z@|+S#TH#LB)grS**C7Z;29yA~0H9SMg28T<7-VOO z`gu*QPs<#W#r7?}jl&p#Fd$uza0GiR_aPg2JnF+t1Diu+kk*pY#zQbSP99xB0K}jW zv=V#$VEl43w3sQbwU&zo&(bqEiCcTwl#wN}p+a7$`Ku-WgknZjp5WkLdCk}Ru`j0! z>1M4bp4W0Dzihdg6;rTaIWb2rGH^183ux|hv5=poS8C40H+OxP z2M=d&QyWHOi3vTt6tRt%}bLa z-4JTJI=1pQM^)9?koQ|qfL^PNwoLZ$aMV}mF0!?y8E^1)W3$az<_eQS+~vu0Qh1L8zvyAlJ2l$@;cbSuSf$w0=#K-i@d2AT0zftsUAf<5VtvM#FT;l`W zu(LAF0po?45_q{&*VfWdfk~;_O0R6Vo3Evq$L)_oD#jhx_X}ewr$>kXL^%K#ef~Z3U+Rw+ z9r{F#TbtTH;3+fUMa$47EBr6FO)myi{>#o$IlLC*v=t(3B#|pAz)KRa&D)_4;*`vM%afr_Xg z_-!Pf*VY7~unViW(_k67)4eo^O*4(805&y+69~mAlU8=;yPIfLRG$DzI`Dq-* zF@N;z4f|%~?N9dsrft3t)MOU-j%3ZCyGi@~t!n7Z!|D9?GX!}vheZ=KoF^K^DKwfV z9Tg{tHTkBf6``>28??(KR2`0(s{sN*uFv&f|3k5G}4gD>voZl(7O zbmR7681kjxzRG#-b)a1Bz7 zoY_BzD@Tlx0#Q+E$#egIF90r8$6x1twM#Ll=7-=ZE0VOZIvOSUxH4Q4cq}=%YXy|} z0;9%ZW<-Um1xz?_2#rjSq6uquoNxHVw;p{szS~1lX`15R?U)Pc7d)OQ4`dwa(7PN% z>frp%116CI9DcMYZ}x^&9SIRPK+plX^ZwSLZ&J(AKK+V;mgpRK1UnbTel16fy9sf8 zy1|%;MZ9|Q0gw3t$%8yOBWFeG#4K72==-m+daLq5 zQVetzcDlP!IgzAdwmdX+Nmeyu;7O@_I?KPfWWjZjl&zt>K-^n2w*33LErs{yWK7?Ssr^2m!8snbfM$FWNxn#*HIXG@84??~^CAwX zg7|X9+j`8*@8Xx!{Oy=;>haPz6Am?S1E26m3^tu|hHLJKZO3(Rt@rV&5A&QNno(iC zo|s_O1?}0*P))gsh7D>Hzo`XyEpb9Ok|n12Q)S_)rPj#J#dUWY@vO%UWelzm>66d% z)z{nCnc1lc=3DIad&fRl*pNliCr;x9?_uM0Xx3~eMVTU_nV6_rM$B!j zeHlSljD)&sQhbce$Jaqrdz)j?!;5nj@MdKW&iF++X=uQ6?UlMKfmLRy9(Nvh)*T zsWCH$5y(daNba4*TAWjcCvAW+0XTk)8NxN#E-_)>{j5%|ZT?^y@Oa_`>GC;0ez>@u z|L0>#ALJODw<>j@yy(1&XZydGr~j#7(@%it{(E@$Q>qsC7u#bIqjn>kcCJQBSq*@G z^^^(6WbT_^ZsNWmyM(IDay)yV-_Twmq(QHhT>6?b?LcU(sPdMf%|}9kHWb*#>Jcm$ z!+>kV!WuS_Dy}T7G^>19^R_v0Y91`@of4FG7kP zD=;O>@tq)v1$M0KbK!!u_aba*Ns%Ip_VV`9A=iS0#whM6r4Zm|{C)3K?CA;n%&LC1 zIr%g(o0DYW#%{qHuDGiGdDqfvMKGWQ8juP=yD9k2s}7uoD~&4EHYL^EFCXO=|JsCA zew~>oG|FyYufBDa#F~Z5kA6G)aQp6Qdojty=T5be3DMHKZ=#s07tgYyVhpuW{LL1I@2VN zgMM=({5Dy3=!=1RXrA|5l$+b}2k3?N7aPI-@q96(Z&eIRvtIOT2ktVUynz zyceZFLJ@wnY1XkWxK}H8KIoK94MUMupXKkz`tNI%TRnyJ45>Kkv zQYo(nIbF};vrTyN;5~o^f!=2yRYd|2ym|p!NEsWARBG+VMY<-!A1>k?2-9451tn%l zW-U2}iCjNVkez#h`FqEGT9bV*2Rab=@;`rO;?rN&tWE!RtjZ{1bF3No>`*2d2^&0ONnSy1_X}D!HzyN*MO3gDjKALM& ztln`&SInrlM(r2}n} z8htIyzXa!{%{|(AnRNy1e|X5e1mOhX)f&rDTGjJ@I;Sc$(q3O)4D=%Wey!DP>{qJ& zL5&-)#8eCaz151L{Zo_N4^R6z5jau+bJ=$v!J(2pyLEBzD|-(=zfbpK zqmdwv;d4K0i7}Hvy0wm`ocZF3j4_-bY`HZ;Hdl--A_OS@TmtKVf zP|=N)%^nnqgXv)wNzotuxx^G7!W1M;hzP3R}&(Ah!>2S>+%W1^;w zZq6V_D(3&H!;*pj1QZ(87v&$zvTR3Pz&i0F>8pZaN zumwMRZIR-2V)0Ic_(av6gZT~(9sPCxFNqaaYPqyM1&2W>5kCn3bP9vaHh5~&Sk|%L zQ+DFt7hWkjt%i0OcKiIq?+VoPn)15dlk(c1I(TyQ5bnMvQpp}5wnmSWN1|mJWHjr< zdp;9FpxTHXMmH4%9kc-i!Nxo!L=k|$6m%ietZR*@T3)#8Y(bTGe+mVHSnA@q(kuWS ztie+GMHj|2l0AZ<{J=@x{x)pBkF&QC}-i?Er(AekCvzU0;@ zY340{DGEPIl%L54Lxder2FD_dpUU)TV8+($3YSMo4NPtD$yWi z1WzL-jZHVkX#EtIBXm4;cRimy|7aUskw$5d6Q?rCPWdt2%N%OU-*ug+;{9@7DIuJ@ zEb=yKQ)gh(xM6~e!>8?{Y@}t=Yo)>Npz%~+-EA~5Z%2AO9|=?gfa9cMN^VE$jV>#V z(suePNW5k_xUh$yqrXrNGNZZ}i-t&cd=sg-zsK%*rE*K}TNqXck9@sGhu2ZbBo`!{ zRuzQnvxwuJOz4g0OfC#Y&8!Q;;7 z(Vcf(+ZtCcLRwx$h9NCXfsVVwT@TA+5aOzeT1O|*)i*w_vF@AXohY-eZ0fh!>lB;r zQ0$yO1!wOn;vh>F|DpVY<@ER5ijd1sIO|Flq*PAC(vtnjTmf5V59(2|SNj7bCiH#n$i4+_gl{sr99xoxVvl z$L1~WO)-Qp{Z|DI`0YRS%u>v>i8I787I|?K+b|8E?(qdOBgRAQQ8OVSaBF_qE7pCv z=ykXG(AwG895A?a66s_}UQjzGFTppq@yrMFa%DMq+!>@F7tN7p>!9gS(}vbzHFBwO z2bwA(?HMCk4g7nrre4a@52)zeD1g^GtPg|P6NdqI04*&Z6eWLLj80H7`40pm15V?2 z(0`lMs`r5&=Ued-Hb!?B#b$h2Ber$d)HcwAM9pKUghSR*trTIWmNZQi8>Xx{rFgX@ z5@mMUxg1hsy`Es}lW7xQ9TW9CaReIVykn1YtH0*CA{vX8Iox)~oqmye8$89m3uXmG zF9~ySD7Y8!{nG>1wP#X|ceTHy>{pJTRwC8H=f~G0C&ui(B)Af(-V6IaZfkTIZG4Kh zP_qQXmp0opYRs^GntuRc%*NioIq-XfrsQ`@2HfvoM*eo*U+44zbjihtCV!!NggScs z?$S@qFr~EOtj2&4^l3{DaYIzsOc0cj8ds)enc(8e zRk|8v@}?gd2_eg;3B2^4Iwd&b$RHSfX$}qZ<+Sx}$9#hsNUzm4fMqN#10+BtLzKia z@Bu+E$uvNaR4G@w4a?C6-W<#jV*lo`xI`@G`xM`^Lm^sSD}v$tJvd<qlo$M>e9O z193Aahz~hRN{V73{_)XA(#lKpTRp-?^UuMRv$k z<}nP(>$D$jm3FxY45QRt0TBLpJLh6r9D;s?Mj4`1m6g$bdE zb`npiLN9}>{pHXU*c>7Qwn`dC8K)?|7k4{jYA?ulyM>m2C}jsT$=ld?3#i>+S5RW!>>@wV<#Mxe+;O$!EG z*;4I#PY?H{heBWeg6P_Xe@voRH~I8P*h68(N2Ywpn`~u7l`^>W(3#0l?pG#rApUmM zxJmrK@{b;0xPWnxaY+1+*I@4Re+et!Una1&jT7c$2adGesLJMNou>NCyQFTYS#4K3 zrVSvEHz}0Tp1T#+QFKyh(KrAlnMK8Z(BM~hKYeOy2!GeHxHhJSOry9@tLKi;(9W+; z1*6SW&kZ6;p>EBdK2`dDnAHm5#_G?+Nd3Gj&0g(~jKhtMhl`2JgRP)7;m{F6y;6Ud zwu<^D)GQAPaq(ZqU7}^bnS}!^=)Lbk_7|E?rkvWmmFF>XEdw{0M_~w5iCp46YUb@l zW8&DT>V;Sn@%KK@?09{RIiUnW_9GB9sS`vMJTe(o99ejvKO(<9?8u3hrp!t3vZxTz z)@*;Y85V!h+NzWnf6_Xir@eK1wJ#T7Rq86f^7PSIB``CJ+HWo*KL6?Hu>AgQaQkE# zx#f8#?)2N^KQbG7cO=6!uuzFc;HhT{pv}l$^?y;f{+|H$e=F8s7_7wrZ%H9f=mYO+ zcv-xCO)?lk+z_}N|^uciCs&aJ^{*eONp` zItj!)ef;cHdMnFCho?1c8jj|ZsLaKlM^2hbAg$s?A9{Bz=S&UkBP4b2eCOW*Tb<SM0nW(LrI?l1M+henrJkhoFB!qb&|GIE0BfFzWJKR zQ09Hgw`xs_SvQ^Ed0uZVt9BMEhV8 zajy?=0qzHYmhIn;bVJ|`@`Yme!ClC14Gj#PxDJ6To2Q`yn1C57C% zMe%4j)ir92(#_xesbH<(CPH`1{FPu}QWbfz0SjW1SxtSXASLhucLfp00EaKCHCR9IHdnG|qt*e8=w}?-hXCZHUBJcy!xkGiSDv%e@4t zdUNLaUrfD#srZr86-m;iAYlC$+;WURp3^uq7&Ra@nIM7_l0ULEav3fn8783|Vx@X) zY;-sv;4V_C4aluo1x$dlYgDU2nu1&d_AANPJA?W#oEXaIZO}&cEOCTYg=Ci-bo;s6 z)~z{f_q0}oyNoIctavPN?(^{5MMY}@qLcYOT^f9S|Bn9BDNs;@i?TRLUA8;1d$1!l zGS03c7`6OSVI`Dl>+fS(PJF)hTIQT+CVY0D6Ygrk|Kaywp}R5f=k zqV1Z7g{M#~iftKKTGGX3Z=~P23s&Zozur7t7QB!YKn05m#_j{|QI|IMr`}}{Fq&le z=mhMU9ydPW1aN>!@vGjPp1(R4-y!?ULw6^4VYzM(cL+-#kh0*$)km+d%SsoB zx9yFDUUR&tCnTy)eEgSQcqJGDvG8_fF;lr?=K9W2;s)!fIfiB-mV)((`d|Z{ZhxQW z2S}r`M}WhOD2D=A?Ph+`0a_oZLVy|y^q~!KEh?8)V>E}8JlqcafZEWC)k1RS`Qr8k z`zUm+O(fAN;6PGO3tHe;HY!NH$t~~uCPMxcDQ>q$ce!l$dgMg){%xUJ+T+R4-w4oY z47=dhxk4P#3$l)Dvt*_87rq%WRFyip^Wqj@ z9e05kgtVq%9$DGxfJZqjEw#-BiWAj@tSg4szrg(nx2$+wf;5gp>|^i5%5zw4o~%NtdkOJ#KtOYci*-{p1gCXZY8vAyN) zFuM}9U_5*Rw3sZH`)lS_9M{q}x6}I0HX|+mA*(JA={QiAsOT@4jCm9q+PNL?>*bWH zWim9V@L5&>M|~a6fp}nQ-=UPq!M-f-(jrqe%Y#$y2d53ar=U)-Np{zhe8XSvWrLs6 zb1DU8WuiE7WjH;gkCZ*Z$yt98`6l66Wl*z~#}p=kbx1TGA0O$_-<$#!$nmsL%eKuB zH2Vjy9R;asI|}cmE_-IOY&QSh7WKPJ46*5Q=)h5O{D#60@(R=2q8ucsx_M-*ZIfou~Ft#Z&DW!+)v<}rt)e;5)rn1{_(>0VLOW?y$oCn`r$kE%d4 zF#2Qx$bj_6r-x-pShpVGw)3u{lIAf;xA`NNPD90MiiY-3O(96%L-;P_vTdN@28Vp> z8dOA>glmfurG+jXBqQhM9%t`_)GQ{eJD;>dpUY*&%&7Di#{ktknX7w1>Uv5c%mCp_?vXzg;3r;~O0*hKaqctG@UQ_BW- zwZyg)cZuW5#noQDDHoaS3Lr*Fdf}zz;QRcTjO&wO8>o^CdH~ zuG`sDMClEb|DZ8Uz@K@Rcz2dC6zNp~TWS4>&{qKU(b_+@vWc*;TZBGb4V2$5L%qqn z$96cH_NHEYR(W6PL%G$lSX^-rM~euROqMqM6mBU^q2d~#|T^ZF(cd3j4uT~^$eC~r6nQA@hp z_h;!D_taN$d|_VL3&avaHh&^5TTm8w^W}zgyd+v2G|BFsekpT+^sFoA0f&9lXUVOkm2eW#Daa6z7%zmY`r z?PSL3E!4H{K9FkT>Gf^gY7Y`HQ5Ww44dh?$d}H=Ecv<)HxQV3+%U>x0Cf!+0DMu*_ z@s?tVE1rh~0OeTHv`Ki$Y^lDz8mL8OXiPQmWk9R&t73wWXfSL)j0 zDGVSjTT$ec$*N5Wpdf81&rCWs5+_!#EGzT9c|{&met)*RThZFsZDQ^1xl`*v?}Ey8 znpz6xEb{=gd64%#H`q<8+Wlt6uUWINX2IUbSb?Yba5Y;mA83A)CKM1fB7R?@g`!nC z2ZRxT%~1iv9QcQE73#bcz2Nf|Jlh8ZX(bu8(j<_n%?Ft{&tALLv;e9MKH_2%pDzw* zLXre)0sGAlL$4V>P5gJK*(~Ns=eB9+rUxxLj(cWyP7Z*}>pxtYnVeJLO+TG-;6$%8 z6rOc_%FN^#ycLHZ_dUgu6Zxwi0I&)Tgmw)<{91Z^6W<41&tq9mr*5bbWCo^Gf_Xwcz}u0o)7@ zQ$nWUlcCq7 zYbz9qIRR+ur+PW{L3B*VUjB_?{QiudkF_F)0~*%r*Fxr%F*8=L2pRNH(;#5_#5X&s zQPG|^(@k<*!tbv2VPQecDd4ZLdm|%V@{+o4^{A)Erxo)$pbLGM2G!Kj<=?)aq!azt zB2orc<>`rD*Xss^Hb3h?Ku?~Cw1`kWfk5|`imsQJS9ijDprXuWfCm<@9-se3c=(t+ znZ+0X#_{y2!25;gx|<*J;oZH!(*>&03T5fax~w6O z_n9Z}p4;RaEF0M>Ihf6iocNVicxho(sk+`Ny)}6T>ymcsK_^jWaWsjQFf#H27Z47Bn+)~a2)O92pJz^z5Gwc6 zcu9f5!6Ei1_AqT}R?qnPqEXoyG1{e3Kl`j{#0H;!g<<(%);l zJ-2ee${0i@sq5KW9Rm>;TjD$TV_rZcwdhJG;8FdG+170na-KG0(?we5$S?AYnw9v9 zhI{JQ@2Rz^-R*qyY!Fyt41t(HBFeA!l|61x;SW4WZyukjOtKsnWmABe|7A7mXo62w zcz#RGD#HBzlc&Z%@P(<`+i&*z81HuzPRz8x#PiKzcgRt-&EBrY_`ijCc12B+te3wX z8Lza6xiXvChLiHq5l~#C@hq;!ym*Y2Zn^#}j{`(pveY(XBFXbKte-qbkXgC96Q``t zKA`x#Rd#@B#!#9^3qhKcPW8W`ZhVWc++*@E0^shT3m>tbaexTB93+9ZBZ*{zcxP21 zzC{~uWeQVk##%pb;+y0vR`sAnUhotrO zY(GWDY4!hm0pk111XkqGanZHXN+l743w&he*yij~6+R|Y;9E`h@)QzVH#1N(5i&l2 zS7b)+JTnjP*G%F0tUzf1#0=$P%TODV-LE)GWC?zA(HweSx z)h~KyHmc76YhdYj0-p?RhbVr94zTjQBehbks0ebjbSb&BBaK63i?Or-{6cUP&Ua30 zi3`#sP?Q65V3*v}HVLv=`|v16`AVVa`@W4FkS4qW>drbs1GC#)$xslQ`8w?aRa5qF zm5(g4{bkzmQu^hY6>6uz+FQ$I8coVDgtb#r7O&E9++qtEb$4zZn!2R6P?Nc>KOt_& zO;~i4G6rD-@MMOmqHL(3)L<4Gn>=wTzaWW9LJo{c^$&y|()bXzd)g{8gI4ylrA&K@`Mf0-RisSb4Pe7L)BTtD;| zA{P@QM<>?)Kqki9o5tw!9WDY+5Wu%Jg>kT=)9{zb*r?JucFCQeYV#>#qL@2BpUOsm zJtkIwH8rZ|JC7z&HA>z~@V+%_YE-F1`@@-U;y?1k=XObRO_N14FVV58?-E%TN3f15 z#b#>p`q~@)#d0WjF~19a0(#k2=^kcpu58xh{(03wN3yxF11)G}!Nvg}C0$^8R%b}- zLPu83O6=dviHi5bzslvlsRX9`vw|f~GxU%>oT2@FEpPGacp1c?0oVDCx7VG$nVApk z)H&Vk5h*!X$Z4?}#0YuDuRzK91Ls`Ih%{wu-#|ZD*-~6+eF8W>XKM*891nDVg+8wa zHtXm32eB{075T&Fg+Y!w;v#r1mfPTQGaPa0z@47);0$_@yfxN1MYQfCne7`VWiC5D zY<3NgSyDA|`DU&hZ2Y=g`DC^>szwq{R+?F{2EF>~x!(=qdi&s`+)Dv4zu6QP^LY#O zgYKRN68X(KIuRKX3RI8fQl$^5zGdz&4osg??=6i}w{#G-U)6Rv=HUM~Mk|@^d-MU~fuq}S(}Uu3 zQE#SiZ6+Tak3kQ9x_S>hFQH_o7ua$KnC~QDecE4;JH%8Rki+|FeANGwe+4}+o!9p5 zRgqS+8F3p|x{ZA+~EAmO_$1Y#ybH5-bz0LaDEuPI~syw9ph zNg`urq)}nlFqQskt-D%DCjX8go%5@GR2=Og{6Jf99P?N6^Q{a|8n&odA~UVNlLS+= z#lY+c@ZgP@zGf-PnI*fQXG4DnnZ>%{%Mk^U{L<8c;3NV7B9RIz-m z?(dn*5$mtHP{#D^^pu~)$kq#!MVA5lhdly5i{aev%}!TIe(xD9tuiV!GX2DB&pAvI zgnGik&r)=%keQ&+i${-3iepd;n@2~l5OQS+sClS)S}uVlF|ew#7mPZasyIe0fAUqC zYN#w((@X2A*i&S2Ahc4P@YaB22HD!_mc~5-IvZk{oixB*VUWiO%_cswXTfgiXiKXQSh`73%!5>4;X6xwS1b? zzQDVFUZCF}Eg|#MNNwFrpO4WBkLoFg49UT-vuyWF5USy7(G^r(U#`oabFZ|aLT(jD*z1Cp~<10eeQ)aDVoWoJqy0&ZlSi9h02l8Da#$P=GG7PV7yGmuru!eYM{m!jLQNmlU`q*LN@5lV^WTMy|FM zWo}lEH>xT(#RH%R=i^hxe#){oE>b<<@wCzs2z?$=6A)xSPx#LY9|!fD0NqO8 z7qzsV+wFtEfX5A|m&)Qyh>_ze_6P)5=S%J);?yy`ZOh%)r?=+)r#9-%9?Yr#wmdQ3 zy&V%OFo?quo9`}MV}_KAk6Awsepy}{cV7LDce3#E@4e@7XBO1{UngtA-@TOPz-6nw z?zaD^Qy^~UK-|2OVnU(8m!+@!lhl_+*VxDNGZLTDVjfxOZjl&J^OR)D%GS`Cr_Dg2 zW2iTh3K)~t+#YN&jB0byC&W0sU!|ioQ7kECrDXuuR!$VOaQJ@d;^hBlS19Vt8zH{d zNt@M44D@ih+x~(a>GUcC%6tXUZ68}O(T!eTVYh|)n%EuRzBL-=zOn^(+;O4bOEVsB zmd7b~Y9jxQbXJ#r+6paUCxj+^8Xg((u5WJEfj1E0Rj>R}>PR@z5wm_c!|PrSrrWHH zyV0)@h|A|7i9UeNcrOUJI(`*ojR{Rsw$4@N3Ia1oF@mM@4%idKlk7~x+nRhlmiXnH z=gW3VDfg=^_Dy4q3Ha%eT_bjLs?Rz>=y#^+mzG=)*MR|X2ZRz&v7Jv(s&7_3VoxRj zYqy7Mfy|+jrEVkhx~yI=D$b7;X_6FR(!K=VC}LdckAq~qaMmS2DH*rA2tl|D$8f{3 zs|{g|c;{K%x;~?&Z?wIAlG9KkJvpAqpy3-<1IjL5B~zQE!anTtTAfw~FoEkN0LyAt z$L5X8fCe8PE>mPR=Bc`MWZYYIJ-hdzhLFly4PHn1CKXK6U^eY?zEAN0a1m{l3S_GL za{gUK*PHY6;JS-=6VKgMe^V_JcfZ;>!t~fR;NmKjxg2ag6z}DE;w~{}?c0=b+LJ0` zIGKmRgXG+WKCryJ;wc^@gGoC)MqItHA1mwIN%sh%?G!#YOqLKb`}+!TV}&u1UG-eN z-mSi{+SE_^&5cW6aPQl22YPzH9vKL6=ug|UTYcr|OJtFOHxKMK0{&cDl;X}s=Zb~E z)8z-WVI_jHcOI!7)K;FC`mE!!Hbs}RS6izk*|Dqf-EqKADZ==dw*2p(V+Gk?;e*Jl zWh0DT#VrVBbW#H8QraY7jG_yRI}HZ==CmE`~G)M(C1gW zG%)_=n4c!Dy8+7*>^b5~xv%Qxzda=Xwq=9yqz$v*zhyd=o3P2v`U}DmfGe^MC6o)Ad`c^|2rN zj!Y^;jMt1(CG%Hjja3&tT)YCSQ5I^D)#T^3)bw+7%=}#&&JrNp0{q?kSNk5GUS2VE zENfCNe#sc`Lb1jGw8e=?bLqprL7kN}eb=T(N zVO^}jiAvPn6Qg0Ov0{O%t8#hE4JEfRwW-xdO;{u~r=%@tX-v29p1jaPsH-Ao6EMxJ zR_C*L8|n&LPCt|WfV&9y`Zf9vidtk>bMK5TN!qL5vW_{u!}h-ZLoK5Ot9??VA|8i{~=t+)hRW_`LC z-h2F26x46=gAQ||Cga_g;lla>G0b|Ct@N&I)Qb9&hCV4`8B#0uyQXzYBO)Q7&To#D zA*29Y8B`F<_GKhCoPecq99EZAYNGVwM{Ob(?D^4KQcZyf$xzvD)?mk_C`f}xQ76xa z%j8p~Fx2L7vDD!1V_Zd@MVBTb^-gY`G=-fnqf4^WA07zMuUc)3 zcf=h(=oqXZtmkXHb{6fro=%JOYF)~qB^PV?X6oA0JLK1DKUiY(B|);iD%Qqkf8r@o zLbpPjots*Et9uYOUt`x@(cuw79FKk6+p4YmJK}!7B|)O<`5FT9eDmNVPWEXOhPLWV zZ9pYftUdf3W?%rbCZJjf&WzkMhRnNE@UQBCyD0=d`6DM@0?D0XB+--5x?gUyRzI^I z-zN#yF|X4EUM;+roM(BY_L_e65Q5RbE?r%Zy9E|rSj4xs=foD!brxVi(rNtG@%hIp104VVx-s)Va(R;ip6#}8&avS1u}nzfH>qZm zr_$Bidm|HUc(9Ry)^$qBTgZ>@?|VB_IM*BT>?-_%f^QajpcmTGcM19LyR#FqCK($R z-I}b_+6W|^zDY*APqVtvhGN0ceAb325OP*``lLT{MC-$Op#Y!OKR(I|onMLk+Knd@ z0}QlsEte1A_)Hofkutnf_xG^(p$C#t>*&$7Z6urDpS=q)d=7gy_>b9Ha4+pMxe;m% zJ=+4jI~-MVxf_kW-m0FzEl+Z!`0QAds1wYMP3^JT^;=gJpspru7b!CjK|30ZuS zm`i7>1ie>i^YUu|fd@!@+PkT|oY`hAo5OUFG3E(bZ69a2fR8bZLdN3cy)I)NQ-%wi zC(g|34rz(>_(9y*>)s!BkSn=~55K3u$XxMu7 z;SJD7DV9iVPv{#YgvDe(;KC0qyT)nxE5lQAf;bmD0ZX33UcPEJrWCZm;PUdf$WEc? zM#~T9Pp_NAxFR`!69hV|?jHqwEn`zM?fx(zl1IoS=Y4R%kR~#fX0kOv=RS#tQxt=P zQ4xZKB07^8myuWy7Je7Q#S|+jM%a@vv1*tLjX2gJcl|oj>TKKj;TjWleoc41=6lp- zaBHl}03O6v*ma(ajvJ1{PtG!Vb$O#_G~5FZnl|EQJ5VqH)bggR57Mb#29P{INm+oS z1jaR|5oshgko7`YLM9d=W-skdy{GA>Hp!~!H?%Zj8Fcj_cOAiVaA}MW9*GyDKttZ6 zW|e$@3I??=5vdw|LGXWk6n2u8?^EkBCPDQwT*ZiwZL%lt?Q?ruFjkNo$`zd*;gDLK zQOe28<^k`6>);*5!+#Lfc%k+r>BpD`kti@G-Mr_QtJ8wxW0kaz;Qxf1@lINsMDq!e zRXS9T*6L5yK1pVQ(>e}TrkDJ1(hhgh zwmLadYKveRs^%Kq(OJl^Uazlyfov|?*iiF5dH(iRIf?iJ#O>Eo9gNKp&LR}d7!QtP zB$4LvO#1u-?iffT6&E&*{>TL8f}{(>!9rb}NJl51tt<6%!x73Be~i)u@rFKpY$2Di z3&xw#f)9&#o*7FWryQA z5@Np~Vi2~X<%fTrCCC4+%<-i`e>-^WP^7?dJy(|R#ky^+$z86&(0=8A`E70{$d~nD z>?GL;Ob8XY1jkxNxkht(t4PT#B_;b4tLN|Zjf@SOHVd9x)5KgjrHv<2DtyvZlmTn* zo)^_h`|^SFttW*-=Z9y6wny{T5ZK5PVp2W1*)qC9q4Ith5`^(#t(_I3LubR#_3;s- zU+2n(WN&JCJa}2AO$Bb=Y(i>$wBKhv5*g|yws<~gt*}S6H&xqd0Ci*U{*T&~;qS`Z zeGk#sdB(t97rloM>c40ltCxQpnDq*{C-&13T3o#I=l;E<{IUk4Krsb7HajW8bsmy* zALyZR3xEIb)ce4)+Q2o~QL;<6sSdF2YR@h=I=LSr8Sp*lbbYS;wALuN_w0G_KukYO)bdSd@OMDizk)ZbX0%c~3 zMwqZ6(S~c%29XuewrY5=N3h{yK3T}RE5R`$hIz_j)6r7yk!m4mF=~;@;1h!7K%rlw z_%&yGG06t-;W0DO%Kv=DyeWGg81U`x?sx}1`ag`lRa9GT8?7DOOQ5(0io0upK%q#X zK=D%C-QC>_6nA%b4N|PQwYa;x6X4JHkG+rgdz7Pfvc`B;o_o%DUvoNZ-nTIQ^bN_B z&DN^LWs&|K`^=~FJVQ^9b>b~8@~=>-mb?-J1N?T9KQ5T7xK~`(jkZ=h1V=HMjS#{U zH9AqlMsh0bw|w7~^*3OZ3omT81I0(sNRvWn#MqW!*~Ruc;umpyRA_nY3d{M|6;n>u zEjmDLe`T_NHb^%wNLZ?HWN`O&WAncIAIo~y^XR|2RpwkRHnV#%FArVz5v9rzpopQZ z&+D}ClHacE<~vh{^RJtG?}J6b5pb^l8eqh{+o?e>VV4mTia$zlhW#drb@Wu4t&Vd6 zHi?Ulk)3Y;0vZ-QV`-c&%t$Mj&A>{DZl)X6Qsy5DRf7F{MUZ<6L6V4?KyEqa)(n@6 zZ87YSD05d`H2th>66y-QnJ-ZD$ZW)^XE`$zDDZx(-?J!ks zV@6y^jHWrAL%=>%5+^N@DyuY2v8QcbsfA+~aZt^21ij8C4_+c1Gzub)so?rFi`0tN z`}GSEb-zoDwJXC9eAH3CSt1a)@~o?UWW)mz`^`H>+2{o1Go-}JdB^vcl)kRS+f{Yh zaHjpRYjVV+cD7AV?B%F;_#C>PbM$+d`L1cEwh3ef9#c{SAu0h?$#l}ncni9}65)PE zLpM6GL<}SeCfeu-H{G88TQ@n-nn5R^(tN_t`y+lhb9pHeHB}7_s74zw^RR>w)8{|@ z5wA`G9tk42i;};+z zJe(;2q4|%;LaqQ4kn`K|c|O)6zsC zPDG*l-)asroD`U2%Es~l6v@=1L_}@Epj!7YsF^ydf7Z#P3}T zDwAZthwe+MFk4r*&D@)FLpzie90V_v7%RR`vcx}^aU%zyKCs~`T^hUjkvP81&sO$4 zF`5I=FTRE}3;Dt#emMMTcRIcEs#-GkI8vc|Ewq%L;+i|#z7Z=G= zc+o}p|4ggs2kWt$*4c4sj2oZ#y45`UuG&1+_|1^Z%Yf*1)biSt|KS@iwzn=^Ovieo z|1jYIKFngJlC`pcd?Zh_d1BcI^xrJvDXTtdl7FHhq%?5+(#!c)}GFr6M$_`M9~kM0j|JCy2x-&gkBT_3+$a9Hq9a zj_iVC6NXvbAH}JethK~7VRvv+z50C@kO9vD%^Kl;UBGeA&pdKa7fLSbIPw65SYp0_ z6G<16vu(b%Jzmq~zQR==cAu-9Yl9N(4?#0(*VA{HF>+a>TFwDT9!SQo=D>-9NwCAg zjG#td9`vg|pITEOWv-4tD}A^E$m|4IgBp7NF;aw^Mu!A+$C?{lzcBQ)g$Q9`mQL9fjULjPjx)Yp|Gn&aV~Z}MZ^!l#6$RG%vuB4P|K_!czrjF?zc z;c$=`^6l_f=?ojLmfSlc6KfoUHEiz)yT3DQCztVM`~U@sx4)+x>r1Vv#~;m+mQ+hE zrG&+Pzw(zTX4`f(DQ_Zh%$W>fQ<8aKsf4D&fzlV(kdeI`vbPXe*FBCkX&ia8YE0i- zk_R~g@rl-5LFL+cE*(C;T?eA2BzUwk+f|5ZI}KVaCA)17{=;Fa>U;$(Q4TYz;tp+< z*ZwmVq5W&h}Pv+K72lhk1@#@K3# z{tBM3TgYU_GP@kKGY$GEE_>wOTlasm<^Qjr=>O%a=pzV=0&S6|PcM51J$3zCS#fTf z|4!*B8)l$-I(d9WL<0MCR8#uAw7jmtuA=OeYd$aQEo^VlQ-$0alU==ru$tGRE}ggg zQ=HAf^#7X$*n{S5%jv4o#T~>*RuPWoR`&Ih6FbKVe8|Q8rUt{%z^Mh+OGwFLAqtuE zGbzRRryB&onXgdzV#Cj>eIvF>SVRSQuUF=XK8?J6Q@Hng**N$Bdks*dmZtPH`hUi+ z+#bp=Q>KuIqH3*fIIwfA4=QZ3%tC*1Bu+#%&*^k{`mNb$_uW`6+Q-BmnhJvo?Rqu?>jTzf|d)CaNxL$`t1oL7~2H_nQ%>L4)$iDNZJ> zJUWsKxl&TxT7eK306QRnDR?~1p9^6G`Ep9{uRl7CyOMq>1H&YMD07-jK(D}tY-P>a zKEo)u+gurSqr=}6zfS0U(<*k$7YRS$Q3j5UyML6n@HkHt{K=n@$Uj5|8;zju48W&E zo4S&3MFMs*PU!u2#7BOm1&1bLt!v=qie?z~cp}O->eLwZo&iUbjw2xgqXJ)^6XHDJ zZBq*LYs(y}7Onk95pMC&EjZUB#X}||G}(_B0Vf%JAktI0_2GB93ODaGg}kAp!lqWt zW00bVLBhZSe{kiuaA|YC!aQyt2$O1mdZp&R*N~3OzCp%htk=3t{eW<{(*lgl-+s3v zW6i%ElzHWdZH@KkVy+Jn5CUwq8V?@8C$4J@<+ zdK-k@aJW)>;lfhzPL3s};KzaGG8;jHZ9~})!P{ho3=3BL_qzZYWS8VrbN=bXG#SaA z6KKAVmIxk*TiBb!=OF@ebpdRy&Bd%m)<;gQrso0VR%0&?41_N6Rb~vbr;MIKq4n23 zlzOh&DHr)SiWD_N%?YW~31q)RB1RY2HerIzZY=P0ZG0amzH9Br>+H4JIaG|Ab4B2m z&%`V9Iqc7t@zYIP$@V}lNT|wx3p0lG|X~#3T_M?I)mvO;%#bIkKUS3@^ ze*bL;ufGNS3;f;>_mP9EbVCTsxnqsaV~sAzmUe2@cfi3Hn?{P_ z+uUW4;_HU>+nQgGHO1N-fZ8`M<+}T@{-|a7Y3uyi_WCX^LjW~dlBOI;9d|U9%sC+6 zGBdW36KBZ7z_~zg)FF#32x~w5!&|OItp@m* znbRCm0Py$pd9;OeLC^1Ebsw`A*De)_jqdHNU@Vt4@ACsQAHkOyOOMx4&IcIv=rggZ zwDP_>u`{On2jE7x1=S%bwQ#5K_`9>o)=aI@cXaPL)dz-tYb`r>n9jU*>DW=&(B;|b zn34~U1jf(;D;~6n)y)znyh;c2R3bU*kR}zXQ9LP??2QA%jF@DtC_gdBvwZSK6sEwG z=T6ne#Y08pXGS@W!OutMugN8qE}SbvX1&uDY;dU2f?V%T?l8?Qe%sDZ&Ue2(tz5B6 zW%VcWE9s*2H9wD-C=Q_5vGSCY#!)5KgulhQYYYl7G@%c-?h#s0E9}z?!cXmZhcr~- zhcRs0L@twiLH6Pr+UOc&ve+uO;%JqfA^FZ)|60UAPYtH~AlFGo| z0A>wft=VO&x(M4R`LBx98;ik?KE z9ep_XD8_zw#`m)KyNc4!gwJa?A!?yzrHZ}Sn%iVc;aoUN^r2e8!Cs@|$@q0m<1P05 z^f>{=R1{8;%ssug9e$8FuIQ4Y78g;jl7#xwar3Tff#m~NXtOUJ9%4iv2a7n)v;UMU zDwY0h@KnZO1YYrMG5vIQf7HsHk=!wVQZ3QiHFvsWNK{&`M_M1^l>Ju$(->|H%J-sQH#Fg)qfY}xrW;^ zz*Jle!5vro%{qWu&FUx51`iKhM?pq2Y_SFn3d-L}fHrXel8zY2mYyfPR76mVm7P7^ zjZ$pU*@jS8^9<#h`q3#7R5Js9WI}R&h$$<6_G_*z7MmDLNXg2z;Cowt9A56;>ew56 zA={mFz(tgC-BHXteFX)+!#x0be*PhwQvgE$MxA^=oC9OCblA-Ogq9V~9~Hc_`MY}e z(`vV3M@4Nr@=!X;@@+r$^d3^VN`0C2Z(z3D=?PZYi96X1*e=fX(7xJ_`UbZ9@`l$b z2B)f5yFxRZ^Pf^k)R$QLudU2+GEf}Y|I{598^rl8Ue(RT0M#|eSLh&IP{_{+6ydiQ=s;$ z_U~mI099ieVouM|kkh1zXSVUlx7ZHfwKTqne3o@;Tz6es=c_O~-d(gK$v`^3nh!si zEVyG94fXWW^w=~S)OAWNPH75-cxFb~KjWZuM)i>(xFC-COuS{h!^-8%H zHwG4b=#%>t%$&w`ZaBNkBw_Gxq177GB-tiDAXOZqZ|{#LhY8)ed-{=EC6}f+G(d?!OPUZX8p>O^+2OaeP#-d?`De4{>1WR znP8=9K?!MN)k!YjZ>Qb&52FpbcXJAWyUzu^#cHE&+1vAMstB_23FDL{`7&#b$ z1iTc!*67c1gk$ZkK2)>^BCo*M|{BY#RjYP8KWurKFjSRiV(Ksx+rxLT2+kd&HB67dJz z`{xRN@Ozv=KM+LKBk&m$5iPKH^+P{L@J496^7>!7OjaBhh5r5%h9|z+Qex5qzMQ{^ z%Q6?AJNW_NH04`32bK5x1@G;S3;qE^=Y2KmhNYOW4CvKJ6zsEn-e zIfG3fb%{+JT6JMI&gdw+kK2b>y&*hqFOHBjyjrPu3EHVEjAqC?mGwrnUqGY&3~Cut z&3Zk%g0mYRuR(rH;&`ayIPKwG?+)g8(}B;)71ycb6Nq>lA0n{vjw#wiyqT@iHP9wY z#P&XS{Q(=B(wfpz?>g9|_J)E#_R}O#0a3>!;b4UWRVkx)!v*wKu*?U#^`-I{e$6wM-J#=}mk!h)TPfEpC}C$nzdb=XPuWrFoaP zxeU7+)!QPQG!ba^HuS(ZUJWw=Zt!Eyt1LiMvQD>U()a$0A|>Q?uOh29`#R2ywH%a5W#mtg1E}YTRj@jEd4C7ywJyyTui!Thlv3W`YWQz zm-?GY=0z8vnA$1dV?xz(#ooOyAN$_h^yrM3n#-&;+w1E#zwdMRTIE-_SuwX99oOA) zo$1-w(X;06%dCviYJlf;oB4g(L7Qb)>Fa;{h{U^d!m^A|i_M_mp5?-j<={!|520P9 zo%=@xOzq!0?~_cO9+{HF7XwsRnu9p_`j(@aT z5j)!p$<~MwhfHp&kl##IVUF~~>CkBtJ3o*(1I=>hx9E|n63zFCY?zDrO_bE)VRwtq zvn+2?$w?~5_1Z-Q)P~3P^P`qe2#D2?^RKSorLYY08FJmdfQ6vcC z6)}sG)DqQ9qr*q@KIe0YyD8cd$%WThv~p=7lURO53>?&#>VyjiNp$HlsX`v+@`Ls} zc#u92;!xyk!_~9!O?m?3A4G$w%uk1Ns{ed-s&(4<69)td(eU7+8nd2s=C&SE_akm! z6>Db`7?Uk~uf?|~ZyKHm`)i4Vgsz5&J)Re#Wv6`EY5{E+A16PYrr<~+FGO#$P!)uq z)qhS=M8-%*p2m`Vko1TsJIq7>!w`_YP8aYsITg?9M%N$}1eoAJ8G&!Nus<(&U(0(D zP^XJrDe;bN1w_Qu+e&85x>X!j4(2s{8usEC475hpFa`nYj;VZ5{Mz8k#QE0y7T$39 zRzZ>91A|FS&o3-UVVP0$yBQSCWBp9>Ee8Ax z1&mUFF;0+#M6kak^(~3WbF=#Cr;Ma$`hk;;Z~v?gmeU?wzs^Z<4QgxroinZ4w#07- zZbJS6wWL6}iPWfRDkGW&HOe9%Px6ZMOdj{LG~S?g71(6yYT1hS!fI%FI;1ij=uU!tYm_89UR*!B$P3Z0PUdgqpWs=gYe>Di~m{u0s8lF1cIG zU2cTn9073rhv*~rel>KsTIUr~-39&a&PEbA zj{Ig;awb<$Sk|5-E=`YAY4k)CE`u5@-ad`W5Tu${ImKL~g2(jf5ylFMLsvDaT~H0> zi(mAuMn?{?kP+z1B|J=O{nv84HC!O}kW&JSMz4!`UU1KuQnpnsj+u(4oxWtiqz`-8 z1S738|M6R?VQmB|qB42mta3GRzY5afLFde^&0Dh!gO-|B1k3}p9$aWZByF$FXYe;5 zZP&dj*Yx7@FmGRxS$J)BtkYqeJo@^?ltamcgP;_d=L8IqQ%wRF9(Y4)r``GoKYw(w z%g{KSCCQIpd*355C&>YG3e1jG^MYr@BWiuG5gQZ*N=^G##mPK}Qv=OMqIU$&!k!G* zTqbq7-$!z=0C5hzCGF#FnrS-RWc&L~KG&Fj@hZ77#X*hQwQq`mLjwat?C_}o4UC&- zAN9Ar9#|;ZIsn|x0$dq+L(z~MDSk;L4$0b3;O{vQflTtqvF@z_rfb218Vk_<)BasYLP;_ctvdSpI`_aW?v!_7};UA;5>QiN3IK^ zckqFd7_cu{@b}WE@7P;_iF#cv5ffK({+H}5&3d(Wr~IgR23NS~$oh4jo{?7vsJJo` zjS{$4MyvI9>fG8VAy====a$P#PM6kuMp^e^j#J{O_GH-LPqWw|K;Rlyc{ z@ZOzyb-4tINGnHfvA5Z;Rj+5KFembWcrhg9)u*2u5; zSo>PNWfW=EBeSz^iuE~viq9RSUMz0aJJqrO{0?psUcLB{fB200+kR5YABay9#;|bk z;fc=tSZB2ZQbe!>52OVmD%I5eq3F~(S@lCViP7n6NsG~b_OUA00;H7(qLNpmtin$& z+XH}}lsR432g2Dfhx!qki_7MC)hlyCPn{R|`FJD}Tq%icOvDta#J;f8kn}kuf4*%t zr7`C|pQ ztCPYEMpyl&gqLj-1j(>g%wF%LRgm;IkmL@2v?TU+60aA-&yO*1+R-%LVj$e7y1M zA#k^N!^6o(Rx`1v)-bs6 z@mt0%Si=d26+A^GB?YHO{i)VtacE&bQ!9?a5XhrAp(NsN0;DVO4?V(aXL}E;hCFkZ zAQ>n{Peb^SsU0Fmz%KIGV9Rz|-?+Ley;J9T8Zb#oMik7@>ZB1*7@RO0F2s~cB`^1R z8Lj=RGJf=-VGM?_OetcoTibP>%E)!|l+C59!{5lXP#Z(c88f`ZU7%rAIjT?W9H|m# z=-~hW6$=u8>iP?T8Z>0Cs9xKEYt6FpnKu>bql>;{YUeA!m~4y&z9h1`3-GshkJg`e z0}UAH3Tr!IYjJD}7)Q%Hq^gqUbJE{s*f_YtE&g~hN>+^q-(A+fjRqoNW|CfOc;aKDgWj=h z`FM+|2uW-e%@C)9m&2j&eoxcxS_wRGnZn5%#Kjt3^Wdhblg;dUUi~jh2TF>^;K5RD z*2uoJ^m=2Choe1NRcBurQd97A6f&NCsmFJ_ITvJnQ^{i)tb8H@s)&3a`rcV*#aq4WWFVwH^j>HL^F9FtF|NCuunfWJB&1Q=&REq!!gMPEs=eAx-B}L|FYRx^CR>3j%{z-Y9*4r z{LbJVV4lnTg0t&!Z#k;nR#a6Rl_^gvC$t@sk))y&{fjk4p-$Ij`5cjQo7Aog63q!4 zP&_vo?JJ;d3WH>^jGx@TNx-Qn?5(SOH5Kc%-eVUQpP$qFDCV)B(&6glu>Cg(>XG%; zN9A?pOz%r>!3o-yJFD+Evb`kcO_l1MNh$@e{dViwrZB#f?`5HV@cN21Is~IHLy%q8dcx+Q$M?QG^LTs*D#YS?s-I{SnYfH9!sg^N2 zU#zFth7cQ-n~8r(hXoF)^0dF6f;KV5NGGZbT0LD}GCUuRAwq8o`{?y-UP+W!+dSK|`r#fh;omerzviV;oDe3IJMS_W5d)O|RcG$m zhhhPksg1F&Kep(cXWmex{R05x3)N(+sMcGm@JI@h4yx`T5qTZy`F3yC?DhaFX zZaRJBcXC<}F$~Sc#6~_&5i*)P{vvzZCp~#(k*8`LyoOO87{8Cn*JJvD0sZqbQ#2gc zRjHK}3)9Lzt?0MEwUvEY`BZM|st$FT`m3swI@_|%J+IC|U6k+^Qh4-@C9Q9lZv34J8Mei6iuZE$6IFn}J{ z1U#owh&sv*mcjPY6c+*6AQB2L2$X7=mw>E#=6>r{a*Pi@$%yOJQY%d7ux(0mh*eKz z;F8ZTd=v~SJq_H)*gCYxKF{emeEqG7vi-w+BKvFKo}=vu@q+0H+qEPabg!OA3rYKH z|DH$U25%#&<1S6@=z?*ZK?a5@8eZnFo&NG-CjY65wEg(309JG+JxImlCYjPE^Z_-K zI1nzf!|QjEisR?uTF1Sf2^_7U%8^@hWY^?BrkJpjs=V_6DYKv)a`wWAroSuPZMtd* z)^iEWLaFs=s&nyIbdvMPJI6fq_h~TuOv}t(UUdz;;z6B&?st>=t&PBCq2u9!eA)-=k zA8wjmElyJ`M~^WGM&Xuy27fTT2-o>^+TfJ6eIPg~ zm*W%q?L~eF3p?e+{W&x#KNHG;vk#k0f?rpoX5HRO8qDn8zGHUzysF@0$}YfD_cD0m zUaFsvC5Q?FV=*pM0V4qs)Y!`s{qdhbir* zw-r*n>)eArCrB>b)+c5ShOdMR3r*)oZpe%#K;>$lvExLQ{E9i<(cB=yf%6pcFh!R} z`k~f3ap+2QO^6c1fgqKtIFa9%g6}ONo9Zk+y2xtrty+5CRaSg@f37UoHQn}`KfjN6 zV0*5v&-A7Am%4a){90jN;kET0dBACYQ#(<7bdiU-d?amJwaG|abX0zfYjk^Y@folk z&B*HIz~-sk$N8CB52P0(hNYFun%D!`H70_L&vJNKK^xx5I8lhJKp`&$ z9`8tIPv@y#!O9~%n)7#-TK=->+fRgtLIbcWbZUe1sr=MkAmH{}?a>$e&D?y{W8}qG zQF%@p`*QR#mLOJg=p!;+gZ(vnA!bY@k;oK!WS?-{=bp5HP*gOE84sC@+B9$=iXwNg zTF`9&lE|7Ov2Q$aT==9D4{->3x(bvTQT3clS?@W$rAtu;qO z$M9#H+wYgSawv6@rLiZB))m9!6I|-LKaLmFFwR+h8AR^Z71&bt$HUPWe|9`?jp#Bn z;s%oT^{Y2Bf9g(88wn^W!sRYJXJ8NcbI(_kIZXd^nD{|K+ExewvyA%p#Fr400|C`( zAUTGqI&T_F5hfw?zbQ0uVN;8N(LRQt_XDEg(%p2Ki7S&2%7cJp8#0n)u5v(WzJzj; zu`noPD!gtWpM|osj{iAeeRy>hA5QLX?@YOy_jE|Lv>wLc<0AH2BG_OjiXt4eg5XE} zf3pC|5e6J}Tn$|Dcar7(a`GJ8{wYDVKUkJaVsk3H(>OOs2X}XGjBGT0B$us7Kf`;&@chz|0v`I;3`uZRETmx-G{%$c{ynZKexhjj$`FD^WKzdfv{ z%HR8@$1M6OZ&Eune9wH@@`~+#?Y>=oo)JR=QIQ}i#r-Jp`bMKfBsD2B7641F0>#ok zTrzl{RZA~A(W9xl?M{jViYf%}T_3M46_j|eIx+u@7f+OR z{_dxf%aph4YglgTOHzgLT*f2?|G=aUoU_J5XB&jscP$yYo%L-`(C!!F)PK8MJiLpe znUdT}&yd)NnyJ!le&zUeV6)z>g$)l_=Re(oUcO;$v|JfJ32{=ce|N~Afk93i4DSR3 zMbW#2yV;~$;4(e4ezqlvyTP2A1o0u&DXVy=8?Wl_XiiRNX6K&~IXvijjUR#x`G2am za2-q(buVG$*{Mg(vJVoiPh4H$n{q>%R>w?|Q`R%^caJ%POK|)4%6){h_uaGiO{VtY zmAg5ulhZ6kN5|dqx0^+AizZ8u(vAm9&k>>Naz*We~0QtL{>+4AD9)- zAtZkGZ&^WF#qx-y?|ki-nI!(&oG^RVlrnu*<1pQg1CE616Md4P-;{$F=~jc+F;usi z`ipLbTG6DhOfDf5yN!Y`Z;R8pwZ)Uajh?9`LkNV0D9)(<5XsEL0e7(X{@j&lzO8*A zGTL}Y2NOEarbW7fE9gL0fJr6Pziy~DLA6UDKCA`Aa6A8%-|VF3ansP4@X>cu;$-BK zUt%4TgIMG6@maf{@D_uJSNcA%Q0f8ZddX9Mbb6Nl-96Xh?zlPqwO<31^`3jWv=oOm zFK^31MoHI9pwA(&NZ2#4DsYK6teLO5)Vs@XCC$71Nc$I&{tt>?`7S-OvODAAB7%GD z{EWnrkUr*TPGM1y6UT=Jz4A0IyO+mwLs4bg($Clp8fZjQL~7d%0Y7bddr><&`L2UT zmB?A1y!|#u`$F&_hk;+ElHtP2wf>ts|Q+xp(YR09t*;&3n!IL80!JKG~#u5{il7;d#`kxgG zs|*CFn&4#cQ*glYwB~!mz}{c>$anaB*Q`D`|gVVGVWw}SyBnTk1H~_05Af}y;~1VGCwAS zhomM&+r20O%Ds{8OjbcHb1knN&l?gRSGx^#Uf)Zqb{_m5Jn(zF z+BxlhSu0?Ffr+ZCf0tJGqcULo1PdP8Tl+R>xv-B1VUZu*BlmyX2zm{dg%w&{`ijaR zuTpd{I;}xZ`dC`B%rIfX11E__DU!ZPEw0{=EEP;T|MW;oq+yVD_ox_ zE5@tx6LP`?X^Xv3%=XoiD$a8LYaX=uVRNEyV27q|1q?{C_z>bWGnJ|v(zq4Xtq?vQ z;K|mh>qjQEnA3K<9?DC-7W!8t%)lv*@ZWybsA<=j8;G(v#v#Z+{pcBA5kae=T8(!SC8;F&Y=j;j`{`(t zr63c{8gGuImXiaSL!JYKza9?nLtuSr{oq$raTz1Y6QS+;BN2X&m&*c{9N)>E z;r@CqJQ!bDycgvBqNX9fMzW`K zFHm`CAQ`x%`rRI?#}lrAASG!{60CrA3g5~E!i6&f&WkMIZ=}KH#?2w<=Hh_VW!8<( z-I3AI4J8DHgS$0*-9$<`{)#{lWel+CdR0BXL_zB^6sPyjy?=ICn*3lKG(q(-8VN!f z-*@?T>@}FN}|GfV4(&iqPYJ-==3KW_*I0;qQ#|d3?eevqQlqI zSlm5cUU#|^?9f}amcG8MO@~Z$d98bmRy%%($>HIhUvjDv97?T7d){sF71lzX6R&*l zj-IYiqpE&fm};RihIjb0CmSpt4*!v+G5hE~_F4&Lw}PO{md4pu3$}4h1rQIGxlO-j zn%bm4}8QyMOX&XcC$g)Y7r(fF-Dwq4$_}*^#`_SzeV?iQKO#yF}4@`)fy*S3sx}KKh)n%3@OS+q%n=V20rG3FKm?VDyE>;c(6ua{sz> z)9HJ)bGRkU;^GS*C{wEt<{WpV`W_7ka=g0Hx)r2Z?AV!9L%aU|8te~qx{-6Q9Uu1G z_b<+AEbb5_3(tkX>%8ltVvig9#VM1%^oZSR!mH3J@WP)Q&8Y0o@5#UE)o1p<-_fYs zsy*Fwda$t9SjY#2n=l4(r3%16$(pv>uhqYsply|YwvjnjkMDm|=kx8V;1nsi)(}y? zNXveIeU|L>n(vhQEyXMR9HzMTmhz^etvD}sQY$p~d1fV9tOaRm@*bKw1{hoqVva-+6WMjw`w1|7-^;P2~kb?$^W6Q@)e%w&K@wiD>Qyt zU!){`O==kLfWKsBG*d&;34=Ygk2hI0wVzDpsq@e;*Qs?b3mB|Vbp znA?>3j&02vXFHlZqdGfuYj~AGHykrJjKOc{uBrIh>RKWhyQ^Fi7W&B1$@%hq{BrKm zcL=6p>DIqM#z?E+llia!4T-E;05`bTW7UN%O^*%zsQn|Mnd9z~P-$h2WqeU& z#bC%VS6RbfwShQ-M}e~bAR9t1)6jc@)tgRKAAixAPw_pOL|-DVAf*>g)3e_IxKs-s zF<+QA5kByU)W6_HATl5)PJ;&Yb#t5oz&*Wv>a4irak=~D0q*p*2}sYyfg>uHU94Q5 zmyoj6wDevWM9n(=5j3h)1ek+UAl2vTMUhAcUPbpXFa9M$t|&^w*!T{gwN4$7>||^j z&_zh3;68(Q;qg;kmgr>99$uaufuIYK6v@J?aY%z`wF71No9a2mClmDH7o1j^jcO(! zjC;AGKlZgc&Qs#<3LzB&cas}jLmti}!@bnNT}qBc!`#L*tdEQY6GI!||9mWT^(PD# z1yG|-NK{IxCxfzbYrGaF5a570b1%l_KJ%O;v#up6l6+apR!`Q>#zp2oHyCJ4e=J*; ztA2B~mgn|-Y?_6nthdfA+AC*yC*C()|Ls`YDL}wB0rkT5zDHv3bv0fN!9@#*m+w5S za?gi6CnL$MBB`OQN-2c{`5VzoYCgC55*zK)Gw3V^;OGTyXs*OvlKz`}{aV=+C zkiWNoE8v_geQ1ABw{b~_wSU4Y55Q1WHGE^Y?x?3%S?sHuIi=b^#5|6L1{l%}0jX0nbKeL2F>FumOKjBdn zG1;+}*IYON42(jTqUg5?-3fZ@TkPs`IPf=F74m0b`I3v5Y`EWkBkN1+3j;2EnRe0w z=tSj@88iS!h{kGa)8Rvf=w|lnZil^KvBHv4Ahmwvyx#)fAQ3k~P zw@FA$Dj$&~!doau4GE$EfOv?lJZQJpy*4h*jc+SoOiWg1cbUMJtH-W3;h0}$$c^UZ z(kSKYHx+S@ndj$+=AC|3N$j=%4P|Y*D#jeiNfb}fHZf5gv0N@6YsLl7AC4bWn`@#K zR!|?v5$Q}OWhaQ&V55N$?J6F3mz%A+k_ra`zImQE%f652lYN4TP~9wX%w`?Krn8n0 zlN#du73VU@Sah>s%S@-PjLCLSE}M$ciegdW8oBr0bANpVvv^=&#I*J^mvzDF^laP$ z0a;aY8T{3Jtz#)3BAWEH)Y{}&U}{lUC30pV?o(*Tumwf>yG(`y@&t!+@@cO6dxY(% zPNnQmKzCA(wyV+v+?l&v9&tJNBDgBNL~7tQ9X1Az464kRAVd03$re`=4TNB4CZ;ce z6Yr^h6^eA%j+|z8`(!%`xdsu=w4uS*i|Ffs^HXNbQ2o{YXAlceBMcalP12Jz_BmE` z;K>QO&A)@bpj|Uv4x!T@yzUlQ$%&n%2Y01SVpVrTUq& zJ1vDl9a!VVa0T4Qd3rZs4@klSS5jTnLY!pkL%t4yau#{~9vqU_x~J+@0%YoBr3lMz zoIS)8^`8FVZJS=+WI4DzUH&OF`8VIR(9G$|DQl{@CMp+(B933waN8`gU zvaRoRo{rS;wJMyvjQYK%!%PP#qS>}_-Zc@KGQ1zddp1ujqj#KiG8l=h*tjnN7IU-034Z8Lj^|-@5Q%y*B2o^aLpt3k(jLO&e;8806VOsMrytp06VOZG%DCyV8%z4?LSlLaRkgmaZd-td7)O%!51jkhk#mT0}hsA>5%MVSb3*2-|?E)Tc6f^ z^Vw|dYt{#!{lasEUjd;8-@Rate@Bs)x|rzXt>STGqg!>!8>=VlpNiSCp0Mz1-`f#% zvExneVxneZ)#hsdJ9I_Y7CpzU%1&LZWi*HXO)uig?7uZEK#4(ex$%GYw_~Y;)@Va~ z=Nzvu`G>>-Q*LU!5ceyqu_L#HO7Ea>H(PQ6jDi57TKX%ZF)$eeY^M#XrkOeJ{lnVy72w~b!<&=+@&)Ik z>A`RgEh-6dZ;DrO1t! znN79GT>Ln5WM=q^WB%GdC0}xbtdYl^%=-j#n8!xQYq5#enK$5-)Zk|6km%88zW;f| zyw__BJIa^fw#!9E9-ao2%k+4_ClOE0q6b~tYfUBsaC!~b0=STH!tM@{%CW^HeD3gm za7dETXd=#2g$LPLITNa+uEI&c_FaO`Nm|<_>hyXhNf(-j>{}2S0_0%L>x@->V`}77 z;1P(%+E z$jK%YxK6av0361Tt6&M5-llR|wEi=>d2lBAF=rx#ndmY8T@<{XIO{6#G(R#w4=P^z8)3{X~c=5aYr3QS_*y4PD15 z7tF-D8r3mi(cF$04081L{wU^q<$Ou(G9gCLWtF8PFFY)5QOZnOxhkr-3_FEq{Y{u{ zukIL8{_`_50F`%czSaV3Z_9%;H7n|lx>O1xZ!rzq_pj52u9s}tqnXt^ilEABMmWjr zIjPB_KZg+(9f+XF=hOG6v3_CR`sB<>CXxTs}Z{bX~bJ#+rtO%X7y!ws=wFd-qtqAw84;Sss zvz(U-+1C?)&(+SL!06$re6n+Hr<@>PpU=td+t=62zx2*41JQ#6PlFm=yp}m_)}KFq zNgQ@6u=}_O7gyX+Zc}wsMUVDdzA#+&Y77-HcoowN5ZIg=>!5bWz!9&l!b4&Ip_KEH z`3#%j>#g*KZU>E3SG$|2CPp$fnD>-p0FZa&&m&%pG*VhrIc%j&2-NDrQpoSEm}Nn9 zcJaUYtuvpnNGbRYkg#Ry%V{W^6H+$s=iWqrZIJ!i^D2*hUBr&BUQ$7wRZQK&O+MkW(#v4#Bcm<-wD&E7D}tkIq}1EG=p_nTg>Q&L7vAW|Z5`FQpcVY3&rWnA4*KW(9VSXp|V z^*rnSCa$yQ=OQjgx;!Srz%gSV+kjb^h7%mv0*E+fBN)lznZ>+cXN;QnJ-^uX+ik(_ zzDVg36mY+V&@2mo{k54kJd{$rlEs+BCr8i57$!pc9=5tWmmSB}xc}vcvDxm!_z)er zE9y@fcvdm0iqD0JuFbsF*=9Z(W=k|vkGb14S_d>(W8a^a#7jng-A_IKq%oOmpmw(^ z>S&j-=56rcFLSnMp|W?1LKMp3U*`&`i`2qnPRm`;7uz8z)8RhN?G$3@V@lTcS44TZ3Z6gENarCopw3C^?SjyY&~PKKE+_!(ngcjt)?5s@5vG<2@9FjO$^5ZL)Ik!oEK&A;WO~{!&baR_ zE*$&(<2-ePr^BO|sK*=WTdnT@$JkfKHNl4cj!x-NX{1w7LTZ2@oze}GQqtWZ-JL^P zT4HnwsDz||)M!Qz7^4|y&vV}M;e2|ZPy4*zcHj4P{nMn-476-K23khnbIzP}M!VSE zY@0s}f?NV|!Sn4~!T)WBkV8hsqL7L6Lb&1Ol(XQlof2qy`8(ZRyI;U7deYS4i;F`4 z;4^MR0o1Q*-u=g||aezt-iqM@+&1S-R^h~VQG_u z?ZU~673N8=u}nLUu9#qt{%mkei3^+G{JAtbW2lml{VcO7m3%o)C-?*5nDjfGP|k}W z(j`dz2d3<0yH$Ye-M~73k7&6T)3&5VU2VqB;mLuKB@s884m!zp5}Cc&U~$zaH&#)# zlK~&9;VFQ!r4h}30Glv=Fhr*ES=?RMFQJ!RRT~sCuw6|XeC5}S;hz@KV$mJ3+=+Uf zr^a`yID;MKMXpbDqi(YU6K8u;3omhW`Z!V_QkeE`L$w4O|_F9YB_1 zunZE$&-+Z|8nJgosZ~UjibxTHwYZdwmvy$6#cb*@IA7q>AL$G_Js-CHE@rBEI$@2W zP^L7*uUf)qc9$EnMW>IWbam3UvoRj}%LNuk86(-|2@f^yH9$v_75t2V`A=e@O2 z!L8TLe@X=N330ea>%XPZ5h^tblxP+j{> zzh@ht(fVymAzGgd;ELvoA?r%Igk5jg57r%3zQc)*NKa$cB9h&n#K?DA3Bh@WPfo-Vu1-FBd!1`c6!lzj&wIn6 zZQ6h=R~8b#(0Rnf@lvJvSP{*c2W!N+GJtir(J%&se|Rzzv-8$1e5duZ%P$ZLazHm& z06O%1jvx8uYk=-dgiO?~4Xr-%U)P)7Z_Xz7-mIze(?25hE-rQ-F_+2q zDk*`kH6bnp#mFDX`LW+0AT0RB|7}P(w+rP6d&eB&=`u>^GuM1VCJWRcy{K2-tJ^xO zZ)>jETDz=&3~36y4mFhQ-um*+0sg{4>Q;;t)Yqm#NCRuDWLa4O9&0v*wiiG}dy>lt>ko8U&b&w7fh}Uz~(C1dH#gN%MWECefk7k zi$OtP_ywYO*L(2h_fHQI$0oldzrfE<|4$3>?LD?RBv*Tlpi_?|oX2KTH`nuSl?D^n zY#pmTFGL%iF4F_EtzV%j*@)00z&e1Hi*JfAGKL}?e%eeGp>Kxi7*!y#n~tshu}X_5 z^BKu2**Od*H0^hPHKx-C?*qd&ilq-}Q})Vh7cOxbqz01q1?b7%b#XQg02W2Dpqy1a zGPMAHTxb5p2#grm$V7$WTbyC~x$h<2A(PbsS9b8ILY2Ye>(en<2|h?f`$39D2+wnKF%TVW8(W@42mZ?z#P+G+Rr6U0;Y;@a=Nnl~H35WRfp^icj@Z zl3_kz9#wN0Y0|7XjNtHwsi{iYE9L5i!-f&cxn&DtZe)?3Sr?^rY^b$S1O?nR_5Js}}yxy$1p~6BQiF`OS zoWSjMI8OihvpGF|)>eh&KHa(t*`aHh#e3tyE5p}71IURvpT1tN9Nn1cE6wQeS(tc> z8`RT&JD1K5yO(`GS+pwJ!V{%|ONuUyhN&S(Kek!fXEra(v7C54LUT6TAUD-2(TNlY zPrUEwFbmVmJk-bpiX3L%cVwAU%6aOY1l2vIM@p8bg8(P>MPkbjyEn}~kI0)@;JqCL zK|~{oB!47#ivM>q*o2y%+w~tKG}dPy8)E)DvcUWgvcLeEOp{p%=~COhujSgSlthBv zNB{>*!%pru+mAD&-Oe+c@p2N~Uh8r%oSQ-YnP9l2Z!pL_kV z#*}i!0Ag*PbxQZf~c3t{>EDKMV z{LnA$_zXrey?D5p$*GLvZwd33K<{t;fsn7gS9npE)dx5Om#RbW>};5Z_*#Unpp$%+ zeMsIK`lR5gtf(WqEHefl)s|}KOQN6gCQgiG&N1i~f4KZQXS%bdb;Ff~avCOI;o?e3 zhyS$5(6slTI~+>4N_mO1u#*?6{@_k)S$#mQAhT)-$~tAD@$w7}`uejgT~iOOsg$gUN9aq@xxGnS#Y>{%CPKLcIoe(5tGz)q z(YazCH15x?V%Ef0#h&;RPt~#hXz*+9(SB*QukZ-PT}@X>@FAB7gp-K#(`_QNiN4*P zlWdhz?1Y9&<2n${w@Q!CNvG++%r$ckI9h_I`Vz?s=_nQq5FYRn( z#tF~ZL_yc}qf5g!q_<|@W@JfxmlgeB&Z~*$=?$Lc#ljN_MUA*YYe9+i z5u~I^UPgDteAHCbL15}wuk z6taz*%gR4~6xlF&YJep317L$b@6jo(Dr%oX75F8e_nikB1~;m7nkdh20v50%0U2FN z7Hpyfkwl+*6zq-v+F~1POlwS5Zmr&TPvz}qr(X^dOXamX-?1A%nxNoD!TO!aOu~*1 zsYYDi8vN?`jfv!hA9o?kEc?`YXxqjP`NMsp0hh?h-<5VDjLaMUW6DU(?+0S!jTsW4 zY$?C@XkJ4oSfLb!J(^-Zk^9IQB3L&D3X2&S+UQVO+P!6M*;yVvN1~2X0qi61$M;f{ zT5P=LoC*pd3oJKlEG5PbtpJkn5Q#4TOX8y7>-ov6V=K2H7oZmUqr`b-kInM$bLemM zJ?M>AEJw(@|CHzT3ncR|J#p3ko9p)V$R_*`aFDkxOaq^mhSMW}2eEm+e}AygUwP9w z!}dTnee5M@6>Kqc&hMB`+~d5Ky3U*RL?d`2v<$l73yCqw{G%6_S$onD`Mb5gBSYMQ zH*R$Fz+|l0(uTF3n5D%#X@0UC0SBeav?+T@FOO?bHOH?_u|0Xm&cDja!dVBi@w?G2 zPXq@AB&abZ#sJL5>QPh3yWn!()FbtLRnqrkY+on&xlze}3)$JLN1IJu-Q5R#d<~sr zH9PKZev3usCc^rac8K6CK|>l@+z@RQxWC+mXTdqBt#u{bKz_Veqj*T>G2PB|AY3 z0BANVN^xDK|D@^I?&KIs9ORaI1$-ajQ|ZLl(J5pQdjHxD7>K;O8EsW=eOY7q4(?5|O_Q z<+H~`JKEvN=}CQM{k5#(c%-DQ^UU5c-vQp}qM<9*851IkQ3@B9uHSAIIEZH@56E z=1^@}KL6Bj>L_&&=JLpXIn|W)=}CUSbBKsLTJgDzH16m!k&@ZGZTo@%={|Gw&a|0A z8B-XCC$Ez@yDQC3Azj%pk*67MF5wTBl5`W?=grA%``gFFI0Z@MXL{deBpvAVgtTqb zNn~Gwjkm$Mtg54*8B4s#bhLS5GC#cKxXO1Bv|m;gxBG=f$`q4wExj_adIk$LzN>JV z@fNIv!|Mwt2lw}PieDP(tTUiepTUrxV-5y89Ab(Zxo%g|JT5|=5Mj+;zx(ZxmO2_7 zC%l6YleCtXU03u(X4jh&>jMNCgzu|7Z=6}sPKjRTy?jb)fHsfTi(^7f(n$q2?4RI6 zT@w5jhqEqb2>4iyt#Gbq2tHyGb*yhz9}Dhd)gIp4zmVp8oN&rVJAd<$Iz1I7Y(S*3^>AvjU(#Oagh7}=K(yvP&&w;>yK!qS7 zao`X5In;l#-W!qugjI(?DCAwKq}zsPmV-4nJ1ikW$p02b8hgJ_{txKbHD;G9-=_2w zr1#jZLWm`0d;kED;R%8Y0=w$i9$)jmi<;R*i2qQky~tM*zIP~3|KU9st+JsF#?PhM zcVi8b0v;buv5z3KGEX~JxGE@?gK$b-RkrzTTmG9S>b)HsggWJaA6T?!7B?LP{v@ksFd};n2HAL7SNE8n#@Ue zJ`cXJ#fIX^VHVi41iZzBO&6+?8lho@H%J`R;FsYo9$pDtpTD?9Rek#a!(m3DXywn? z)KW4z6Kw4VPYd62qhf1l_mO{LdlP^3g$#+^GHzED%x~sTkz;m{H?K$1vkCl9>w?`f z;}t`$hjAEAdc`Dqu5KqNv_D%zDJi0pjbKK@wZDASv?YT=7<(Ow%sN8cuQM4!^vumV z3$w3SHQt`4JtfidYgrc3PahI0L_-fhw#>&ec|{yCxH{6)aDO^``LX&aFs*rp$l}-( zNCf#d63vS@eO+F9b3Rz5M8arF;A*VJrd38htb|`KWZ;1QO3{G~nzlcZ9)QWDXS>_A zMDn#?S-d>qgAJ|YmJ-d+QOuX${_;86K@9^Cs>|NC6t#1P%UtNJc^Go`ykRA6IlVqd zZ2AvjjL*~?I#(TLso*vHIq6NlqJQ8Om*%L;zM!7$=u;u%1yPWs z0#K4*_2?*}^R@sG7E`+e16pRS<*E#L)H$qW0BdFy)Byea5akJ}zV(?IXbw@x)n&cL)6weu?9X6v{>MKN>@HK1AvfvEE94k{TX zy<~Eu$6x*Dc`_gk$5wPU0lT?hoFtDom~N-z(ki>*MGeN7XPIuuRiB%|1zDc>x!J} ziYxYsEor0sAW4J{uU4Q_|5W&@yZPA4AE^dC z>Qc%BT9>iPc9(+pjb#;%4 zF0YyqhBoNdb{P|scH$K)sZLj#I#w^o4{xtmUGJ@3`GZ-?uG1VlB}Klfdb`$AF>OQ- z(kmDy*JJQipd}w01oC6jh%v}{2`e^cw>Bj*BwlC5EblN zuwfnow5PtJQ%U|X_nmdiQVH;`_x#2awlvRdi33Gr#?B$FrZ0HThLf#hG4{o!YB`auTuig#BE{V6~}gTa-J0| z`29-2H$EZ;T`}IHy;BQe-Nu zXmfwxH~wyY>e%HpeV3!%QiYm85aGB5rk+@s530vLV8f}~JYVMHTfh*$5-uZYxNB5XO?Dp17x%skh^&%yWBA1?Ip1@({huZUy2U=sus*>-(FJWP%1h!3Vt`7Zc=(W zQCWXw0=kOWpI!WP>uI*6ZczSJp9>clq!)C*F-H%LHWY(YdbZT)rlqIklxAP$ISKC9 zu-#+2C>95vu0L2CU>eWOs7=Uy0Ug`CR$@es{M4vG>5_hCN@FpOHuYSrm*ea_h*0OYcj(6o zRGO4gcsJGCSPq(`D`e|{{gtbOGd-l$BXvFRdym}yAGkor=;;2_ zo9?Tt45bi!xqVZQs|n=E&OT1azUTeF@vohCCiBVmoKZ=(bCb&lpu-XQ zn^*rWbpl!N?@J#rW;arN*tg2+6>NleA{aArTm7#(aVOPD61v@+DFWFXG z!QxbS5B{^QfG*yM8N^MG78YyDV-glWDTR$?)9bmhyGX-m8KD}V2%pcHVb421`6G_` z?^Yz0%_XKH7GRT2I9>B1tG~?Vj+Tq0stF`${mQ=lJd0Y#V_-IzEXXlz(pQfhQ0G2A zbXhfv62z~)F#?ztYFd3(427YZP~_3sH2WI=v`X%4z03F*`D1gtY%sq|i0r(vr}(fj zLlCQGl!FPgAE)0)#uY0Y&a{NQA+wJrQunKR9Tj74YmmFX%iB~KAd~1L;qXMf@Kt3V z$27p9pYwWDmhx?i@;a2r)(%sTGl!A|aOs3r=keDs>L}Bc!j<-mxYW<1wl$d<@&u0d z>d&*B1^T#Z(No6KfWnXVrJDRa)uSK!zZ+V9y73I_g)=Ln3`o7V&TD*uB5wvJN*CDb z8+5$xgO%h2gOBIn%;o)nxQvy#uXHsn*5#Cc%Szy=<||E6rEl#yM7Ln3LfFy?aj#qV z_gOF( zYI^gsRQysRbE0x00qD(|X|1DA8$83U8)wT0>1yCCeUd@5(R6Nl#T8@aUG7^~gt>2+M1W{M3|FbWf}ybzS&a zUSl_V=+V{T-H?rvKl6qK8=b+0Z#)7Psia}IeHM<8|3(y$-N5BCq+g`MBz^p(9Q{s( z{os6P7jPbsqr@D_DtdEqk=-0<-Kx}!xx#nxvPMBk?E0B=(>UU{IJ#TSXLexrAZp_W z)rPx_e98aL-pCbLFQkR`bS!PzS#ZxisRm=Dld;q9L|b;)tKL(WewEBE&)?hRcSG>| z{Df8|GZyCFV_MES2J3&;{gw+;_|feO8L4yG{M@ldwoKpq^OC8XMpZgeHKWQ24R$Q7 zZ%!F(q4%W+PrQIMU*$5Z@-gG={53C}C~(*vLIg{P&k7**KMgcL+gV0aRTne%ZxYj2 zUOnEL-;2I^KDoPgZShA}va9n28(TSE*;Bc0QsHm4;<64{Gk|af5!Ved;xy^_nmkbf zM!ly+l0P))3N{_mH-^6rTaiw^MyJjSr>%nsKrp~Ko%Evh9uhU)U%LHHXgyb$wx2f% zf^jj;eH6WkO)pQw*s+yJ+B`4K9-&`HO#Hz~>glQJP&`FtlhtVMB(m#3Z$4G-&r zDyMMaH0YG;8Sm&rHYjgng6AUWZ-|HQ?x9|Fjl*tr?p*1^@JUbDSYtQfeOgqn(Ayb* zzlnjNxX2h8C3JDu^UKZG#E6TJuvUf@4RR<2OU@J`)>Zt4Y2{y>a+VZkw&5X6QRx22 zX+R8tyTc`RKW1+foae{;S&Z2` z&=mIx_p{d|ZtMA|jeUuE%!l1|Tf<}lxF9s8i}=?EAuop^i~f?77$pXnv>m>N3D#u8 zr0Ql`5l0LRA*bSx7E*6+J_QWUH}QtnXLo%BiLg#BV@~DoOioruDE#+l{9l!jM$)8v zu#^VcMg5%*W&cTa1UevU{XX#gC_kv{dhRvD35ShY#|NjlOeB(p=7FNQ2odz)%enZg z`k5cEd_DEj_~rjEHf{oR8krM(F`$$Yk*x}C^gmJN7}jPiPc*pgCVU?5Gq-tOSpOBG zJY%Kr;NiPm7OO~;-dzNZV8FCIa0+Q%Y~IQ^E8s=jS3L?LXY2TRJ2P$W%TjDem|q`_3O0873vGc+aS)9>~0ku>YBqPaJ7)MoDrngf72^Tx8-0iYxv|C z;Q{@kPcJDhowcZ`-)1op=0e#6C&rm0J3|1_bXW?+nhd`ncvR@@KelPp?>_a_s zN^-s0C7g@pER;&SOc;F+;vV#Yqdyhm%T^q8jHKB+BbX_jq;SDlJo-1&mY_;hp~ty zAmS~Fgt}4y%ujPX800gBgSHnl`R{FJNNVQ>44tW)E!(Q#QzCM;tjpr3`^AwY=mgQh zQk)0P>{p78L|{{+?n7e4!JuMoae4_3H;${uxauaxGED2A z)*l`%?(eJ0p$oHGri6Nj3lkeYlR5ou3VMr1n(t}v4FmF+`F#A)@z@!k#iCesknB)~O1Mg@+(tvn?X6@3Ai2-xo z(KGY+%Ev3MaFRetkQs7juVRs@vL+pI%wDaE`FYqAy znJQPupxM>g)migVS6}})d+q)*M4c0k75M8hd%5DCnq4CV2A$NP5B?p{#_46=r|&xS z`%o6@wE<`2^z3@---GNh#UVyaN;8t+VxourFCW)Ztct~9{g00(S0OGnUO|8F*)0Er zBwU%Sq3YY5-)A+$?fTT^)?(5jG(+71TS+J|Kp{j>`4&i+%04llK8EgU6ke$im^oB+fg4AVnS@@wyJ&0DSQB5ohVUM z@(a}5|8RR%sa1f~q^)caUFbcXprqbH0Rjul9b6G+VvQnow-_q{4|6hk5&KIT{LA)B%*Z zIe09XlA$8I!;j3-8k&m5jwD0FnTsMy2?D)az|~?` zR(vy*?Rk&H?29OH@zHi56zyvQ8k4Aommj@jrY{<4dwTw%Ra!^&-#Yxst;(&v)5O6W zL?Eh?XTffD*;SHmu6&}jFao>Gz%GbW17uro!Wxkcd^PX3YiSVgrX>l4aI*g_wef>r=QmE*`6YB9%^9p~wQ*=63m6&uCjUL_WtUd3>4R%3$DXsLL=Ss0s(dWu>K{#O~ zo>;LsX+?j7W+DDXf4rpsthGFbJI|R^j8tjC5FaWh54JfVakP&2y~Llo`AD~ zvFM(zh67Jm9JdKg0SmJJ+A+{`YOcfKVK2B5L9x5EF?wTuJj-Er_4iq`B36F`J9mro?KkfU&c5@ZO(R1AIZ`UXOCg9#D2^4tuXrJ%i<=+_u z>{S9hG;Tr>P$C9Yhhj|#_RXvRa`={q*ekzOs@3uNBJeGw;ulLPT^d^uC#}pgwt{XQK^vg2X^*T zbwIJduf#~m#qR(RO(E@3E}M(-z{j0$26(s6wjfEBXYrXjZhT-cMJtuR>vow)XxwWP zUb5qznoFnh{4-^hef8F4^XngA^^_K|bKVReuR(N_= z)aENtTncM~YhcYgU4LJz>v{C=7Pc*Q^l`$k5axB$$p?=!$_cjAqik@7|Ic&{Y3;HML4h>!_2g zq16LaXb8ax4P7h=`Kw?Y;F}~(%DBD0{Jd6ZQ{p?4`|UPH#ExOumI8qeLHzCh(|RW! z`Ncrr$KTOzAq$z!TXcGzXW-bwoifl7#Myvd)97$#WZE8KHD^5jXVur2TG^58%ohoH zyuCR)f4qNHbKbMMx#)3_Xja$>)~iYXdB>$Zq8G1N{z5$1n`*}ghkIT*bmH&wQ%gH` z8}IWH$pjx*S{#|2(#O~glz7}|J;?vm{fjCg6HQ$fEI7QxyZ_BkBHg|M$$*ZcKHn&V zbe|t0@is=Zl61JaxXjyyHf~vk&bcB7#kjv3LeSP*TYhUgxT-7b_I~{pD$8fiz*29EnY?n$=d*Dyat~ zIml3W^Qi9$>BZX}4U@W%^Ui;?#w>>+{*BF#3nijA5~Taf!c(v3u73Q4J$}Eq-{XZ9 z_L#Uc?cNdGkTawJ`6D$-)US_*G;9{iHGWdVc24N~w_^>&o@ERSp{5eKw%R*!%!O?Y zvQ&hAa~4o!t2aej-XWdVIzl|;m9l?GM9h^7OXDyXGPL0MuJ9dNWLfIF2VBus*FdzWJhV#%9s4k zv*yk9vYPgK)}o?k)*aGZuTD7Z|Hj$d=|zgmNHO!y$ICJU_24l%2W!=PfJh)vPR=MF zM``Jf)YfIW!r#r0$3gN3&Ck1U)>9kBt}~)Dr_6CNIWcj{2RkG2bGwp|0H&F_F3{~( zR|s2ByNF_BD_e{D>0az`MAvhHH~wd36h7_HctbT$U(I-ORw_m-?!=n><|vn>>~H2- zAB0C<$9dydJ81J)i0g$tpP#5xE^kdiA%zq%T|LyKe}7mCxu!bC564qNg4>4efB6O< zeL`BJ{SM`LqE#*a2i;v=j9Yyw*PULGBMhvsA&~z(!>AOPVEOv3z~Ix07#@TVbJB-h z(OA(q3L&DGgA}x!DPD@L(N^KEbW5WHU?M#QOeWDkF(F?@PMT@E7W}P>JN+U*Zw_W8FQ%AHPt7G)(f1F%U_<4uA*6>$!)!-~n!VrbfK5LAp3#O`C3K$yL=J6r&U=e`JB!zhb!8vyp(j0_o(n_bFXSR9lt3ih zj7F6TZBC;n5%S|^IK7=W_L4(Dv5Azu4%)MHCwT90XL%w*sX=xD+RoqN!XJH`FX!y zNjx|I+wA>~MT;-nY*IWEUq)0gF5~+y$#)?tFs0n+M&c^IGq>-ZWxVdjH*synUjrX8 zT$y9oNia4sA$UUs7LuNQII}N30}$*MA7WrX!#UFA{LZubmEST>88Q7POh^J~RnT$gqaIcyaah}&ZK$%xhM$}8uJTZV6~`6iyU5MQ`3&^qn~e_mW(dy`Na@PV0? z(dZUj@7#K^S!h~RWE)@l#>2INW9%J65Oi^Gd-|TS?=CN?3GJI;sPEs-{)3CJ-N?nk zO8D7ml_$WqE<<=+>`bfWmFubmbrUJ)=Ls?f7~z3?U<)kHh&1D}UaOw-1&Mgw3j(IP zlA#)o#SBxW?hj}Z-3_seWTbx3*c{H2o%jIIs`z5i6lmz1xkEK~LE(7bPCJh+Ip+ju zcG0J|$#r>#>Sr?fg5GvM*Mgf~ZlImR3}i?IYY}XL`&XxC(#w2~Re8&2XmR&`+mn;o z^o{n{gaGlYO$aWRa{qXy@V>VE_Hs$0$s7mFX}9O-uDvh)1hT`ykh)JyLj0jjQns7# z+)N3l!L7aflM7!Xec@KOiNW8JD0QKxmAk+34+TQ)=@W=4u zTPS$F7iA-6QJi|0#f=6g+tSu})@@wHC$gBV;PImv{vi#Yvx3ev?rEDRd3?i1%{o}^pY;?nM+Cf-$5tMy5WbAMYVgxt)#c{{Yp_i0Z8PxYjvCD;^jDe{^bgobE65 z4fod))9%ydx;;=^KcXczL_+x%MDCVcPzTLEOd~jhHzjqX%AmfO$Vjp2nRCrS$7KQE z8ewSUUdc%ZU$7bO7nIE?m^aMKpsG;w0!@Y-Fa<`q3y42phrS?3t^FSUv+cRM^z4ho z3U2D<%|dVkW*2J~B|iuYDFrX>zzhyMBNT3entp z1xg@!W-;}_7p*BHrSa|8_o5o1F#M8w%6{=Go(N%59ahwfWcpoG62q2pKD3Q-Q~i&p zGsanHo2h$atdNdXe+74DNmUA4sBc)Em{#jts_$j!xehQ_S*ji8=jnP-JPLNRfk?oSzfI%&`Og%4MQ zKGf>SiA^{KpIT`1S61g0?OC^*Cqk~jl$fe*c}pF8P`oWDpSyl=61zJfu54i7%9LmP z&_8s#S$ex)OA85s2hj}^6kbv-$z{fo;|R}W>4JT4t?X{Et&=xbdq;e{R@Nx3)Hdtd zJEeuB&iPSFp}6UsXf^SUmL+8g`A)Bc?Wm= zU-A5yws+khW;$)kV=}1b1#~Fz@-eMwNYCnAx!t{f_tw4eg<}5TpNw;Y?F8mssx>R@ zY|8{)2A0K-*p>CgCJ#t5#hhu7Lh7ai*KA%rJTGnS~i^y^V5dKu<;J9&Sda1 zc6=)A?BEp+JTXx^f8w!A2SpjeGS9Y6zr4-_J73(742th~dh3Uxu`7)$qqufe!Ik{4 zEb=SyqzK&4u1Jj;@R^V0p&KUG46CX?`UP!lAfUK_86Kme zqFTnscSs2MzJro`^;b&%VaLCc;g9FY3F^DSo<3XE3vAM9-oxx_lVHR@06=>Is3(G3 zyekWc*4K+2V4_@iQ5grP0Ah@leG|KSYr z4+fB(zIAicY@Rd=(aGOdV~+a=0}y8$4K`9({Iz&XcLtVOINj#PW-%>vwVqM|dc269 zVPoK0@cONOu!0LZl-RN1bdfZ5`t%~Dq$a|w-rlsq7=~dQi`3mY_k1IM7boaeqjrx^ zy6U^CqYPtrK+4yZRymA9_vDIxr(EA&gSQvBb*FBe%#wdXcW$n`^9nQ$7M&m_)YAMU zGKf$2C5l%|Yg-r|Eis3)9x#aH^ku-<#*wOb1*1#gYT7#_%{P_cuM2%4)&ytZ`pe;t z*9SX0Cn(n&%OJA4Xo8#$8eg@*pSDVue`)^4oL;h9MKbeL{lvtYMX+Q>)$*G~L4qV3 zKbL{R^?eUM@d?KfA>~8`Q7n__8eRdIl7d1;juB8m*^i;shZ7TBjk{zfxl@YvzVmGc zJELuiBds)MA%~p63%VaK9WWc7v0~IxDsoG|n(@Xe?P?y(dg3%&GG}CRIGnBhW3Y>0 z!uun--@@xnV{XVBhl70=5C5W29q#(rz@6@^^7$SLF1@D-%ty3r28BGQM*-wK>UzaS z{pvAZ8DDv@esbCk-m#CCCB-NeY?T4?u1-@#I+ORvs^zR*n75hY%Ot z3bjfZuQq8*JY7fG+)1YE>jc-pU$2T{a4F=8YKv9>9Mqa~q=#lQ#avnNc+pZb7k?Cl zI2^{j3zA&)yY$q4gM(JpG9R?%xR!b`V5cy5VPD)FT(6pyk`&X*L?YB%*VFPOz%^5p z$#h)mUp&C-&E4-EE3?L=k&Ea%E}Em9T7Jw+x!|uYE+(^zLUal}4|lVkp0M$*cch|B zdYm++G40AeICcA^83(}y;VR;;%a?FK0V>RD0v&w$32Q))zH02pLVPD@4M)6A>Rok@ zQX>TbKe7Z2$&?S+a=jnC(Yzt2Mrdq!J-EM6s1`l$5ul~JccQH{XJqzR#$Kuj7M1e5 zCuX;s>^&%S1`GFe^m?P>2Z&96fr5EMyl0@D*Bz;nvGbek-*yPJGP;)7)7du@0r+f} z#^>yvHZ9LyfDb{;C7(FE%#w`d8g?|wJztOF_#kIFjvv*Sdp(xh<*m*5CLe$P0|>z4 zcW%yhzV*02dM;EP&Op^r2ISe@mQFR~&^&FM1o8h)1^hD^^j~qxpg+MxuDcs&IuEM3 z|58u_wZ(o}K5R!`TZPEUWi_X_jqPl!C<(`8CP{gX1(P-3TGL(y8|}9{=WklJNiK3( zo7v|${)ESEc2M4~a7DR9PP%+05zf?9gi6T7{6gIk2xW;X8fYgjSH73m;ot6e`E<*; zWz>RIG1pdaf^?{w8}d1Rx5S>TT||+PI({%yYeG`Tw13P$*gn`Cb6eA7>_O$Kv>+XE za!Pn!)z==MFHeGu@MFV1Cff?#7>Gt)Z)}{C+&iTYmicvF5O|(-6(B=Jn z746Gvym?a3n1lxF=pj^B&(x6D+0-u$spuGcZmrBVDLae5WAN9x1x4nY-5cpTZhQkibn zf|g)juC=E36O+bvFeG3LqU9z`H`KFg2=-}A!0C$jmx>=29&KiYxSl8kV5AtWWl65n zsQmtzH8uoFl)Cx)ikY>y^^=-B8%(8unB#!Bdx8u^2p6V%!Zo{Q+F9+w4hwv%WL#k5 z^Nzbl+PbAoT~fmb!4_X8A{4C?|uzwD(#j8R-S@w=*p8YziS;i8Rj7)Hip>V{i(JO zT)tgHCN?BczwUm|`?De6Iwfzw?7JA74Kq5ol`A)lr@J{Wrm6^}q>~Nm;`_j#)!ZQ0 zqh)=I)gFz03 z0xqGZ2B!m1OYYnMAtTY#YD2EGXCQlhR`Z~N;{}5Sotnpo;VoBW;r{i0+m7HX{|CrE zc$Y!gL}ax>{U&GNMAm4`ETk?&(lhP)Hml2&T1_vi8CvN&t{5yus1{IMjN}QHps;QB5ggu{b-06EI|t}V zq&dK=BpdL7t;8Q74=!X+%tV)e)N{5ter$#xL@X9AobUdnIo4!#P%tT-jKrY>&dw2H`YlAbJ4^!gTOIEi%t}tkXe$h}w&&=GD zJa-wc(c+RwX;sW{oPK-~1^c)tpE0|u#d=DjQgxa=OS}QH9y2J63yG`D( zXSAFmyJ0$^Pqvn;#a7_n;T+H0Vn0{i^5(W1B{kwG>7yN(=h(RKcIT}5ieVw`qPMuj zn!O8Ny}@B4{Mo>Pqy`%j2j`84n`lh_ZAtfVS*31JDGv07;jumxIp(9NNRC*;m!ieptw3=rP@LfI?k>gM9SXq%1c$)Mf6lWn_dffECl_31GT*Fu*R1!w zO)ACvkn84qgYWXuL`@2DCc_(0H!Bqe*VLW2+3c=(9_8i*L>|v zgOT&GFXhzvzx{3sbl-MB$#Ji&PQJGbtB1DxMBvw#V+a_^VwFjl%C(XS!-;<6@GIoD zi~`qbk3FDx50}qQ|7#5(p8DzD7X{YyYg$VV1H9vR4tr}5&bxB(&lcL4Af>)Q?>xy_#!N--M zr=^9*fgAk1Be`??Ed@1HXfr~F?}J90yjC?KNEK!s?%`hxyd3cff%cRplWy=j*xx|= zre3$LPo6TzhaP}}wk7b1Dxbno+qpcrOWj63x7X+{y`JbHLxUdXd1HBKxuf)qKbHI# z3lK8~23K5PNY+T@vzSFd+H)o=NljFQ%8T43>aw1hxP`GihM^Jii5Ry}$!2b4B2}>{ z5z2)k?g0$RTmhV&Z|6R`{*wH$B|njtv@q2Q1~hGoR#^J8TmfI17%*I9b8yB;XAr-^ z(YD@>2B}o?Agf_)3qF{4x zLDVp6nppj$$Iw#W=iRXu5)=}8XbfSdAoMwB378?{d=(K0EkOF)`)q-?-0=0twA`IA zBu0usjVRyT)>?hth3k_fEk{n|Zj<16PhkUrxjyN0)mZ8hY&VXEi#*8{hk_ zdw`0UH&x}_t+ZSNm>subhllSeAiWe%`Ek*8#|Fw9!glQWpw!t@@$UVC4M7+fd1_n^y{CF_1noQVHGWH>BL5WLb2n-HcAYe8zNdH6RhVXc(sf;YzyyaEoYto( zIjCRrofhAEyv<2C=d7eYty=6szd>u>b_~}!kT<-7Ec>sb%%%Nj%}L9Qy~0^_j3s0S z8U-_I!bHK_7|J-yQKu0X&B|oG@y65fNYB$Ug4U&h6heF5{`Il;dh4O}jPlXW4COD| z&18{SwAFP(_3j}UdomF=&rk2cGG0(pNwK(0x@bt6OJo6J zlRn}@eh~K`pAD%=z!L>)ZA=ZZ@aPOm!>;Z{}uyRQ$$HlEwWoZbg^%3>yGC*Hy>a}<2>r| z*jrgsSqV4|pg|zR0FL1;8~3V_n3Afta{aavk2z8n?vn`iPLRznO|&u4(aLG#$!DSUXm)E zz^_I?l!bD1!w0|bbs6kC%pe(CoWrRo?O)|>a^rOob50c*el~q|WstN8r~R1Xr8|?7Z$wkoFW$+5vRZ0+@nY=gv8+)}f zLXP$j3}Y*n0bd+FzLto4m(PjvLP%f+nEVE9{upch*jmxgJ*V)^iu4?i_&~CZK zdq%b}0p`-YY6&{XS1vi5_8*0@wMmB_XJ-hbSNNLrvPH=1mV&%grKh-baZRzEJu#VS zG>G7t(mH83gLHF=73IW8&p76@Lq4R@Z7=C|rC}K8%TYV5E%L&H z-mlIn|4s+xUmW&T9ph zv7Q|2=8w(JRxQu0rpP?)4O{U3=<5+S{SHpk+OTH>^_hI+m?b1TDZabMg6-EK-tEU!lzXvT zs!W0BGTY}iNgKR3B}Y)7>RS7Q+|c!nj)ZjwJeh)(#BbwNex&Rm`d%SGRO~pK-Lqt< z%HaBcP802FlD^th( zjvqrfh(j}tI>IPHj+TY=qh{%qR1$~AGQ8NCx`4VGx&x#)DbdWSRWzd^NR0YUQzec6 zIW252tre`U$8kQYM4GPl!rgav17J`ijdaCmM2tXUl&vi%=hAnqx{v)}%qu(e5&P@u z8uGc@pR&$n+G<)+`CK0^O~L{BclCtvTRGpk98DSD-87)8A&(7G%LG}jt8woxWm)3^ z<#YqhG=#R_7RJ9i!kt@vFd}76dbv6{dz|+dAYMwG^X}Pt>!T9N?75vJt@>h;O~gSv zHBd9~yRs<_DyF`_KS)JzEV1aVX^NT{`VPK*t=u>=ne!>E{Fh@7zxY{KC*(zPf^A7$ z8!%(%x3La8rHRsD$DckKp95Cef*#sVz)Y{4&hLi$rD=y3So`<7f+N}mpb;YSi_)8q ztLNX%-PdZq+0N?L+}h*GK-J%?eUJX2ZKe7YZRI$^dR{{~lH{4)EB_lB>F1U30XpzO zdS;QDKoTdJE5%l^Yi?DqM)hO*e|3M@9`2?ubJkoBlGBo` zQEjmYNlDb(YfVl8--;vrKB@TDa94zod1f)G3q6@--SjZ^@+@ob!-!y+prj+0&D8VG zac*m(hkx(5{;=Bu8?_#i9c1V;YbovN$8T*7xf*@DKL#6(Csv=&vphRpO{^B{O-*+n zXZdqPH9Sw8$f89?Br&Oo5sj=ecD9U6tscPifP5hAx2MY95G~(>m2lj{%8Hn*V9~=c zAwnKO9>u$pwPIlrWW0o3&dw2_kXG_>#3*IBW&aPi298@9tq%y(F&)|Ph` z(ML+&XFvosP7`iiQLSbaFnXh-A!Tfr0^8oV3U9BBBhp(<6$A&*9q-oAZuoX7)cV!Dk z3TR~f&K@ZCyuXbEcD|jCGj3DRQ3llAUt{^XTwY`GVoOk~3DKtfGqI4)s!5&R@+dew zo`>VtvdjM2AI`y9Y^w38&ENP8k?!|D)57+hNJH{- z(jD#2GU~kZqm4qs6hv|yanVE^aXLAu?z*ez@n&D&lHaXT!mLMzuZWV;qfb7O?7rmp zC>`RnR57pRONV{-&mZ;-+cMtPu4aYbTED3PjkZs#Z#r-!Mnl*`RpkcbIHG`!?7=Qy z2IJD%xH={WVUYvBjg3>GPi>r6e-^rNBx;hy>$)dl2y!aKVWa=_x(vqrHe^qOpaXAu z=?@&(F!2l~hB+#$P(t|`rvt!WnyWI;2Yy!kK5U+8GrYHRc725Sz%AHUf!YD>t49CZ z>7V+t?*GC+&^{RXo4H*5C3ihu{K9SBgO8R0F1I{Qxp=?iO(bfrgh54IS$Z{ASVe?e z{RyO;)$`Brx!Tj-xs7u5H)%_3UTm-T$Ea!+7cx&bHg^Y#tf^XjJ9>2~qT9}7Sz)*v z4P?VF1w>Lu4C3vt#6j=MZmu8r-MO+=ReQ!1r)KW?JrarBeZAP4j#f+ERHP%1|>srQ+MWyJx7;0#8OA^AFG<|9fk9 zpOcp#Lc@nU(Wvfqns;?CAF(xb7Ptlxa@al|2!8tgV@`<2Pr&+0uSUW)I3GV|1XB@D zkHxEAezqPCl`{%khIC?qME%3SUoEtS*yI$${fO_o0$1jZj8%~lq4;qwm}}j;6~K{Q`=A!`%4&!D|&9&Hi^CHin0Du^#pQEKGzAKxIq4o zQ&{kZnjl4XPhSq=9C_k~oWnj#W{IsrV+XJ_em9-J`(;~xKDCGJ-jghaeyi#IDvagp z+AO2pxA^j&jyAy(_AK~7KL)6{9)b@4xgYfQ0=1Vpz+nB(`+r@vH2KoEC5);8XD^#_ zLX&cg@mtV~5*3x4O)6lFr&YsMuW#Kz=kg7%g;o~dbWSYRmj2#lG@Ex}}JE3I&q3L;BeyDUCSYwSCH9lI>iylS!P$3^d zGPqe*?qf!LBO#b zw5_}GDXAoqSL`lMN9ADT({?t&Bw3wn4c=}PVtMIfJE5a!A}Y^GKU(GOC}(0Cn#?iE z{BO*)t$;r)Eu;`9RjUG~lQO={9)WnqeGA^~6ochIG{nHzXhyJT#%i(qL*QY6Q82Xz z8{y>Rm4b5sAA3oXO_yHvT6uML!&GzxulxS;&tuqS|MpOCXTyJ0PmBmNHd}9JPOWbZ z3@Tz@q+4FMtINi>MSZW1h%A%#9i#3qTt>rQj>|gup4?aGaqCVQ>ZQ%=a%yCzzg#uo zNiTyfuxM$vB7kR+#7bu^><83)x9(an|8Mnc+aEF5eqbf6<2TO|ZYdK*(S3biHmsN+ zFei<0ORRpUxZ#w_Yll_*))R^r7tn}uJ-#x)h)5KcVf3HiXT@A9ca9;p8l?Z-JDnN; zeeQx`KRa)D?4f^cYwQpG&P7AN;DkAA{Zv1-(KnwxU2fhkXxZw}ownS})S!q127s28 zlKl=Y`!WLsN1xu{B={8*VKF7sD4qe8_T_I?205?!5gerzWEv$Yi726wLTz<;k~F82 zm4+(05ZbypZx4+UH4wLhLJ>R@4KBytvRNW$q!-RrP!BnyBsF$WvP39=Fo;G?x*t2i z?I(kAweid2aZ=3`DhIR)O`Cfje?t}4Ac-` z#av=?nQGCT6TY~=*l2R3wD56sP8%$d8XbR2rk{bU%}f*E-Ox*0GtQMiDci#Pd()~~r z8lDo~HLX@s;gH0AOuY02C{b0u&+1auI`?_H1CPyrKwjhI2>Bslwt4ceeQ`8cH2pZ& zFpI*i-=juNU5Iv$P|Jis9ZjCu+MNO!hbdIZ7#XpsAj<8V&{tZ3niY6ymqCS+iD^?Q zB~vU)oZz-vBugw{q?P+LVQy!PbwPnUPAIdOJUh*nqJ>IlN=Bm3@W>&@yE8+T(&+t~ zA(GZrH;~9>*q7F%G*x~4I5f!!_!<5$v%|CXcRGdV?g_@-+VxYC3ilHISpA_~RFo2) z>cGPUQOMPm&E3&%!Dvy>yKRfJu5j-cG&SS)6aK?x4eM%~R$N#ttqJz9&iutNED^!$ zL}A*rN{}2#@w(>ab~E)X9!+_2pxWctp$kANC6dq~l*E~Z%N;p*ru-8Pq{J3o0)h_h zt*f=%{iY!Y(?fz&!t0NpGSa*$1Euh~Xn87pcnDDw^{OtWIF6`ay#cM4j*5^6twiP5 z^+(EmAqWxh&u>f{>q0<#ywKXoH?y^x1uOQF*IH-BDq z8F5On-!9VR=)L+zUdBc!SPRs)JG)4|gucn z37k8;O)YKl1k$1IQ+50!@28FlRCnBXQ246y)?(-L6pm_g%87~w2NglKj{}0Zm>_;d zu9P9T{4}%N$VdzT4}j9`F9vLQE&vZa9zPX|Z2Z|Nb@D1)ZMkDEEGT~3_{~>>x{~gL zW$&X41w7!JK0$aqY-`-Q2;DopyX_&C9eqcX&5I+Wu=bkHsUnu5EZ3v^FR2C4>uTsr zLtQzNd+TznhcUJ_;KW;Q!duSnlcROcYZ&@fIwBZFA{MkHrCY#P{v_bhZ#&xHOE#;r zEb9x6WML*VY>IQ$woJ%7Ew&EPK0P}6c+8A_7>Y#T5qx_Xs4Aa@)>P*LBAVg_?(l-*cCHA8^i!6|HZ80KOXh1 zf7buU@0OgvG4>}j4&MKHm>!k3Bwr|Ui4>qIQA*%+(3@KPs?G1u!vcRtxbiHN1fi5K z$YC0d96fn@Xy~M!eBN)N|Y!4ThSt?8{n< z#u}iFb8B=qUnJGasQH*}NTd(oP~k?yyRw~UR@2gsBgS`~V*s$vthI}L3ZA~?^b{yj z`1*JP`bdg$e;S+5vWux3ZQ4I+(J1j_ZHd~Zgq)~^b-CSt=3MQ0o;7#nkLL5Z*P8j+ z+JoR6h|<;4P1Uw9%Jk)3?)Jf}3SncjiOUS;x_?ps!^ZRxdH*#nNCZJiRFAutDNR)BpPy5`J2{x1WbCRf9t#BD z>|_TDWM<{`UW2!NUPhgqXWA(Js(ZRf1FBJSD`2V7S*P@``2T&~qFx0ryltaUhd$)A z*^#(G{k#92N5lUacQ`d}2_SdJ(6d}UI-Bj0Dy)%(ZC!8;iLa>5z8oKg_qRg0OaiA@ zU0VIfW$peb;iSfk8pCA+`OTnQ(t3}?E_h6fP1aCV?}KPKz^MzqQ-JNOAvEA?3g3OJ zUm}ioy4h~q@^%JyW{gVr$*MT&z>+fU4@0*t>4m7he+B9b?Z;WG_frvz{A4?R=oErG92tLZ^-pR|70hPjHr`%-+M2?UYuh8PjG*i3-J$Lol1RW2A3MpGM< z8{$K;02lg4;PS)(acvW_vThlL3tvS7U&TcqqIocu6+?gk&oZQR>zT9%V8R46A*1sK z-Dho!PT~Y}&g?J-G<%<;^c*OwJg!P6J8YAmGP$qr`uaIwM${)V&i@N zKn;VizKV_Z0k18JGdlAR8xXm>hd#kC)L?jt_nbn$jaHl;?<0DLgKJp1d@r|XxV^xl zPNuy&gsqK$DV}Cl@no?~}pJ|yk=I`uit;|xEA%Z+BvFdVQURtw!S;_OTJT# zqGh1)CKzJ4D8~D$WaHx$Sd$SWwDqsuzsVQ9=wrcX!4+uR58T#2#}l-`KvC3-P2W`| zashU!ZwnVv$`$G4@r{bRum$f{9~)#NX0BI{CAqk?m*o$_`BpT{y0#L&Pr5dSL{#6f z=lm<-=qL0S=u9_qH)`24@g#P9_~@gfHBXx_p>D-fziXWwre$;b!BpBZC_Mg-(L%S~ z@ig_wSk?8a3_B>`EVXn&-=75`4R0$m&u~E~mlj8)!zLF|O^T@xniJxiZr2oiI_H2Ep@b{6vmLCiq z96wd>dKK)kgj`#MGW7ey^s&W=EzvRVe?vEzW@Q&8!*;4gYHTY_q+b}Kps z>F`ChMzu=Yfmx*zVSr+{+~i^TGXxkxT)!K zr7jhNPv~>`+*6B3h0m)%n5O!^=JCycXD4JUlRVVp;zLS%w7g+AFZMG{TL#MUr~yGW z%uJZmy_8tgrL2XUsA*EA&Ou`iPo8ZpaPqKrHweXy`MJvx5AU6Pm z8*fY0ttDiVY%Pbdiq<5p3pv)wK7M{*vJ#01(+yex^@ebUi+_jmhyB@O}We zN&kRHANAdSKexqdeXAt6aX&qCwf<4qH%Q&8*w?>S)`}5}UyE2!niEjmegsgs-K-DhI#)mpSk7N7HGG~GRMoT|*F%y_i*^O9+P9#_}WHlS1p@+dS5XPtN`jmJuANC z18@V;|GURDtlS?c6F;cYyxKkFddqk3oO=(tsISz&UM;pPQ-SyPO@AF9JzUtiJn1`E ze9;S^9$0JNezA>Q_-eZGN>cQ_S?i7+p~IV3OD+qNH~k20OPNT?n@%a3Ip}BPeFucd znE`$Z1(Yv~=4Cmv`{Bld zxunFNCykfzb zLEC9)|HyhoY^=94SFb397gaEU$wa{{Ydfx}=9mV?U+ov)6uv(9=eervHl z>u3J69+KT9&-R)hae_jw%@H3%@Ge6>+S!)?dV34KkdG7BR!Hvoj33Ljvq`+(?ThP>SeB5dKH%wTn_6di_R1`1r?_X4dw+T~GL$oacsSz$;#}%RG2Ke%Ml4LB^FFqX4 z`>NYM2c8iTBf2D=kGT&CTkSd2Hb9E*^+lWTf=1&qZAKJCP_~Rod~b|Aq7q`z;ErKr zC@LzfRGW}_NSasMBwF(4NZwh2{p?wU1F-WHW76X^J#MHMs#I_qg^<44x_4xQ=KVP2 zpMv9X3#p|EhKUO)U{mi|)jPQC%~<677P;q=DM4~%XQ7FOVe_{OJ|+TYiex*M?T+6$ zs|5}5H5|bgKvC)K;?1RbVdl;`kO>_UI(&B8R_2&Xq`ca}4EylDLj_P}&xH?N`Cw)F zmLb!Mw@Qx)_r<>tJ%pJ|AeEpN*p8v`=b3%b8neEBJ&`S?NoBdC%K-| zxf&&Jd+K~$_j4u{ijeJuSM6K*rvtE@f>nHScfe>KiXsx#yQHaj>hiDp2PoqsX8kE6 zS=&y|&8J*UUE;`9;^WGqtD&ZU-Kq7q0igI0jN6_oWr?w%nV0oq$xtC`!$`?gRW!iX z>JK47sHN6{W2m~V+{Z5GU0ph4N#ZVS#^WzJ(Da5y>#MTEOVI4`wY$FyMtQ{1*p`D3 zmIN9gs=hvCB)()z@WTJ84CKV`tr!MJjRVMMqXf!q#*2JHGP#^W(0?a^7>Zh$nBDYO zrp(avt1&>Q^s0Kb*Yo_(q}zJE1>h9+q?}1~PokAd6;TpizW9Mc5j$ff3N9ylx??C< zicq8pjr`@t5=^bGrX*7PVI~irf+<2uYEqj3lX!pSc_YvBgBm%Ub^puFtV*(5JkC$Q z>j#Ha`MioKrW42S2{*ai1Mf@fDK_I)y-^O$l@?*?oJlx{Hi!y^05~tbAq0ne*kBmn zxpXYj1GWq6oeCN0*PHh_;Suj>c|Ie2PZg`>{BnuE;`+sQtJ|ljX%(|R$-w@XO)94n zKpw&OokA)zAZYYTU1(gzD5~Z*G9Np*7L&U!0FM|u0gV9eR|Xe4;1d@uv$38rC5Hd& zMI8?~rpFzD|8-hb^es}HT1tGhd?yxVHC(eE=adP~in+R;tF{W4fFVe+0iCX3pfH!3 z6=!s%p4w4ysQP+h3m!MzrUYGxECo|vNgX2ydnG?Ac-E8{4&EW=9vonOeN@$TcX4jo z>0ULbe&)+B{5%z7z{Rw#ZZ&?)bXEFE9h)W>p8mQjdrRQ>_!wDPb#K<@xT^%^dyn_a zLmwNW{7(V4t`>)VJs)_~CCaP-T%2i{+(pXve@k)Ej&{zqv&d3&=mWGOL-+WtGpZ>PNh?YMzcbg)EJ`bcS;mX_PE zHYIO5IgPK!T^v?PeQ&N059fi}|B?!tN)Ck{5M>duAWf>$C=rmEhPKINah-luy-;8^ znk49osfIO}9bu+8qh>q6?4_;Mco-<5j99+!1_{^CK7Ug@z6^)EoLls<9h(M{Z#>qh z-hp58TrIoJJ74duKfM@q8RGj@2iS?e8oXD4j_udL>M>IMf2>E_L{!ZP@k}u$GR5@*h^MP{qA4Kn}1B%k%L_$WR zYDGlWKNW~r+~jKRBo1W#%mu)k?9Y%zcQ^JD_)b-ZDN+m_-=P7@g8WtCJawj*-TuZ# zkSp;JB%(+mg3&s4a;4zE3e5z=7ZD`Ts*%DemXITOVXQu*tK%>gk$f*=2=~k(-3mO9 zVo?fJQj%ug>NE=}d=HC>ilMNhk8(1-KFsOLVTL{SKAZF??T zo`rQXI6&u|!i7QGbHA!zc}$0?`$Lmw`QGIP8g2j1<=?aOizAhiBFLQNafrvv$&_65j&nQQ;zklBG1HO9}EAsEY)STI5>z#cp~W zR{mibcV6upKX!@6g~rYq#!X#!s+yId{o8BQ~=JWrs1H|6w4rv9b^C{oAbB zU5=XdeR>K<{lZ?$OP>_bDA}Q3R%n}o4%bxuSsYmwc51dw5|O~;>1*?Fc`eexKi;NC z&9L*kT2Diu=+oRLnL?oIapM4U1Ua=fs&(%lhv&9)=s8x=eruJ1g`#*``py)p2Nose z#&z*od7=G^KG1ET?gX1k%m-4io9sw4*Jk_eGO|mucHUw$Di}WONMKG(2!qi}Nj_`3 zR)5mc=k)L}k}OvCW8LhyBKdWGBO_yp;H78NvVN?%&7-eiJPl}BoWU|TMQbK^@xs4; zef_mU5?d@J!fSNjH3y~(cLv^5DUUEZA~YBWlt+rg`MFMB*T#sX&N8xTOJpLcSvZpf zwp-#X(3K0l(r0l5`bfh|U4z)0#%(F8JChB7-(l?(=;%8Aqt0)vGNcu%xwiSt5yJU6 z9^u7~VSLcl!7t?da(@r*dJWVZvTKITs!+C!k&M$_kPqV1Ics1wN08B7%f-e$sD7X5 ze~_DKy76#fh0_6TmBIHZQ-)jqGw2V+@htHO|n57HPMB2I-Y zk}FRn6!fB2(ZXlh!9D{?Qv?ZKuK|=HQ=f}`>Z(V@+q?tWma{m#`GEVDXAa$d%NvBM z0$B2SMkt12Y7N87b7}eYh+4S9 z2YM6LmXTN1BUi_AuenD17LV70_f&Zi3>(Db0 z-09+ZD`>iehkT1a( zc5%5}%9$+Dq@)P)I5zoGq(s);=? z+(bDswnT#HJbNJynbdCNx!DT#MDFw?r&o7~_Mv47U_{Bg46Lb7j zrzTWCGcx^wsmPqJpIU+zemW&yqgE(#GbPoin z#PV74_e#KZ;*4J03n#!IDI62-i7v!@)vz_n8f+Xdn1!u zcaQ>`%8!{!EkD<#}nEQ&z3KzLba}=yeezHLo-gFivNWHN4yUy|XvyQ5X>*ZLUuU3!Mf6i&<1(#`6)%D*#l$btT+)2R+F4WG~pZaHy{&*GWT(%_NK zx@4;a$dNrYk;3koiO;Z}GJQ82zCGKyxczZQm{k502LKGLPQ;)L?B#E_iHBLd=o%+Y z4FPMvy_x@5;y9I2G9mbI{I%5GW{_RbK zC=ecjtHEJURYvHnrQJ7>E=o8MFR|LdV{1ZW(kdkI@(8w3ape;f4T4;OUYbem#cUoS z^^4Qdgc3RfbJ4HO*}@a!amN3HmK6FhpMa`~>byF(u_048jv@n04a-Xv-D=x6y%V9J z=uVkN?jdMtubbO-O(kdiJvS|*4k}5BWBxj|g=7#aHz{>UJ7AYT?HUOhn_*;+Ljv_# zL3OJkGu{}A0C$l?5SKNCx;wyO#}X$Q6t5*d{PJBuyw+QyJwh^l)oOm%*PHKEk+?~t zDx`wQ|1)-?8}>$={<$i)hGqG+m-pH2E(eOrcFTYMox@u>@7|wdqaXjN6qT5GMWA*c zV`BF#wio5Qf0yq#Sx7hU4hxFMpBAmc&x>(1b|oc2)+?HJR=Re-<~`hn6x-aq@o##X z{Gm$~rTzIC=HKE_KGvfsx90ul=@d4(f@Fdb%Fgr8(Bb%IVb>(e$>nh8Xt3AoM{g=Y zVK#9B>LJ=%r4wZ%ywnf`$j44zZ&9cQSCrHFNz~DA6f><#OX!ShE$LWZ@+s~+Mw*oW zd0U0#{mGw_*hyz?Ssp}YPsi6Ioyt${u4g2@!qT!|E%w<@d7J*gcHR&D{;c&fYSyv4 zo?AY?&5JhQtz1Los+-F4TVH7!Le)q9L;wmK!Hu4j6fd)<)&|q&_=$) z=$(+NtXng4q)P<_->1l0B2i)| z5PviwXi~y%v0u5cGF<}>XZj|Uwj_n0cWascJhMZEsmANf6=qB5zwsmBYlkrGxuOfE zhC4IZ6Pz}>?iK=A`Xq(lhYw$WgvVfv2RnAqIySIn#aS&v+wD$Z~2ox0<%=CQm!`T8;YN}SOFN}`?Q%VlQKP6+j+MS zcpQ=9i`=h>8bT{)x1IsrDIS5pBG?Uk-KOG(2MUZuw|brfGs}rRHgI_Nnd`;nRr`jO?e(C6c=ZLH#CMCbp8LQ zNxx+UMCQ;m{dh-qef|zsRH%oJB!?ba*X6g$j}=#|`yAd@Z%m47{E-V=L&mXrbA5~j zh0gRfjv=>k{|`pZy@dZoau+*hoUK@-{bSeoT&S$`K7lazMf}U6dY5IMG%AP zpVcDE*NxMn{D9uW=;i8%Nhg#%qZ>#Hg7~NK!%W5+E6;e8^MG&zL>)gHKqn|SlTflJ zyI^=CwYj!{n>)#7TB+Ece-i&`#|w1A6F75zkEw|l;jK#S?km$dJC$;)|8L{)gi90V z5SJ=hN1JijZktrbYmrZ3W;mnAzHq1MY(rW-#t`Cy`&f==sAGEOq9rsGvj)f0+DSWw z0q4^j+UZd8AK_d#`b*%qEK0DzE+F!a{)t8>=(s(*kplspI{D z+!3*#Ac7kuxvx|4O!b6W%p9lhi&t6~l3yc7UVC)yJBJ&z+3_ql9Tq|FsDv6OAbRLlFauKG5reL51zQIu(gFH`yxRSUZS zlg^DiRL-#{pn=;mvr5@6y~U18*^tY2-E7IZ_^cKpDnUEfKFGv}KPY6^BpJqrv4`lE z{4?(BjB^yTqP$$)^-^eamMjCAvOLn_Fb@?FsVWXlzsd~qv~)ajwM)i-HoN;tT;R*Z zacuzv4*MV9n(|YNaYkwB5CafVvU0q2y<`~?FPqr7pN;vAWWF{;kyEf{51HL7eValqc1*t zargGQC}f<7v#Vv*?q+ph#Pd}_jO@Hd^wV-5i2F5E=*8_8YIZQs{&U6>DY?|>Eo(c2 z(~UCT#a|ptQb#)uE|cKE^@@=<_2%{=DdWMFvWMA3Titd)$;J}|W~O)*5HW?>9#0nM z2Rhy+uL>Ofm)2Z9Ef_+{8Ylyd8UgL?@a;Z5-A~@LPmH}uZw?ACAO9PS;XloB&sUaK zjb^YND@qbX)xmW5qVjX*w#GQ{MaEw9FlqMkY}N{aV)K2$Kkvcl)NAazl8}e#F!g5} z@R{(IR>Q&mCGCqr^>=vMDI!78u9c|6ir*D2vSFpwQgq(8nh-wYa6r%k>tz*U?yaIV zUNo#8At+zNO8}=8xd1@%nB4yEERcFumzbd?fvNqdQ=!Zuxe$o)(|Ud78pqdoa@v=q zw|Y3Y)z6>f8&d4uob)-!Jyt8VqyillLWvgz~LghUQ3gYN)bm@ z^k{`PDn4?MI)FWOFd2UW7417|=_K5u` z3o~zIv-LF~@e)Q~)meh}W;?dM5F7gR3YTBhcs`3|3fe}Iu)yZ3a3K}WIOQSK97AZ5 zs&uXY^JDlUbXJTu_G6r-`i6hPuxi(AnCh#fz-qUgm=nHikmBO@H(C>O@=oYtEHjx$ zB0eYNWdt7^2M#S*w7zUcOJ*BYJ-5#~+C*YsB;vsCpEr`V=OXpL{Mo z7%%L|hr6;Het4Be?*&xAH4^Nc#rE@oJhn!4EpBp_Eq-O%~KAMR#CC z$0;B(R@L;H4_-(4_J8L@UgLfPgFsZ`h}4SQ_7o5CwR6X}Ch8a?3F-DTv@sE1Sc3Eg zM|`-PBlmO4cZ1Nw?zT9#y=j?;NbBj%!)RdRx0fuAARicek(hY6%jo@|8IdJb>6;Oi z_lMWY{fnVJM$Snc)pT99KdR{|adTugo?vmT{3YXoCZrv$tq$nu<1op4 zXG>(cO#+ht;QHyN(;Dd}ALi#rnsEdL>QP^n{11|91h_4Fcno%feh0c7eqUt+&zjGu z*HQM)!RMfuy$$%LujhT{YFapF>U3}z9w?^L-h&u%g%`K2_x06BOz^cNXA>XJ506vO z`ezwK_lKpOZUmg z$E9)PP*xKcGvn%6g!gWz?SvnqsW)fZ!RG)&Mo5kz*tpr&tZ zxlflA--4}$-ORu3f5Ovq^TYHWMsMG9ILcII+t^G$@rgc48tWB}-At}iL5H@hu5mi* zO&pcARa6WDu4^mrwqLmg-~MTh#-4kD_Qj!d7vaVjdn}}Ci`yS_4~3BdaEsujZJnSo z+Jh3Cnu#yx*D)V4xMIE{%It{tJ#_J}B|%#}-Lbu}0B54`zR2K{U-7&MJOD3qEWi|x z3{Gg3Sm=2y>(&N^^!fYG>PiyKrXZV)7J=s_9la1wV_|hu#p7H3 znW&et@k{!X-0h9H+<1VYR3m##x5Bj8c3T@tJJMgu6&--q@KMxnyTqc1(ujnyV`5CB zX9NAPyswg#BqA77-IpPmFiSlaZ-c9#j@;+J7nBvRj5*yU0ni5vHz%=-m$po>*LNvI z`~Hp_M!5WJ4CUVr%?-Ty%sDDnoY{v+*i`04+h4w`mA?{Hh(J1Ox&m&_UnXiKf}VWT z0z+V<;ELb$$CHH~x;)!iF5XYNU&`^p`M?gl+#y2i zBXNVO#u1bgEj9aTx&85(GSL99zQgi(g@3nwh-uNVIDx1He!h;Q+=AMxT;2 z!0!~>Yo8Z(L865s0x)xK#A!^YAa*zLSXAAQwo}?3w>&H@-lc-^d?2n8LtkI$_f#a{ z={S%GiuG=a;-F}RoU-waQM z?V7`Y74pe8_g36e+L}-@)2Tvb*sGhhy;KPYgu-WxXNYXE)v@Y!sgkbTLprRWdTer^ zpCl_?6moe?Zxe`t&9J0d!eSK$IiEiCBa-X(qG11q+=Wk5+O@>vp*_5K<+OajP+ve! zr((1o>k+^LFZvD#HI2&zD~lcno+(4FapEX#R&`v|4U{SYVXk2%4b!91D=2UwmDMT^ z;l|Pgn4E55Fli>7W96lCCrH&6p@4CU1-VDckct2ahwmy;8~wC;YR0Pniv=*$#?h}Z z;EOK5I&P}%NgV0wN}_g{CT`{Nxn!e2$&@QBpra^Sbb4z7$2;1)?b-TY25(Y|1>8Qm z_?2^M{j*Guo~xo+$1T5#nAJ*R?Dmkc+;rpoSxR>5L{}ViQttf0+f^Ac3J$;wC<-3X z*7~hM=|}!REBDnrh#66XRCW7Br$aIPwv^r#f@fG03eSv44bTiK4Au<7M+_>>pfW`5 zYM`(!Z?3Y8On)Epaz;%l-kOB0&a2d1Exl-$T-?zTemtes(m>JE^wwq!{qcCY8Pc~| z^Iq=$LPeE|5`W)L<51=}uC=468F(@T#n!@*n8YF=LtH@b52%o?sc>=o5#Rk9PLtN} z^;ITuc$PQtdFbxmxTDyY1||txA*D5>JBkO|i?`2tzN9pC-F{FDV4!F)RSUmiGn6#? z$ET_2+EMk+B1V0{6dACE(BEnvhlf=D7{+gLAj??ti1OOW!G(uKHhOCO5fzH~ZM` z4$UwEB)UU|O#6(gOo8SC%c#X&8lIC$Sw+Y0z0z#hlz zsU1@SFA(2d7`Z9>Bi>KiBqv>Qb~^ovMG)l|clovth}FcPq$DB@+eQma(O&I^#V)^N z{rqG1lN7sMsx716*vRANmEBjfZty$|OECx=kY1hFz}&bg4!83+$tgAiQoB3R{E53Bi_kuP| z5NE99k^Jj4TAOt_e$#OkyC1BQjGPuMIV0b$NSge<-1`Y|{~1;4^@Xmmt_a%l!yhtF>3TCLWD zFGG0*?l;^;ufobjKWO>bZV2{GlK^YqeNJRGOO%k{t87A1!^}gVpy7I3$0z~N4!0K7 z>S@UO60L)afABe%RTwaO*e3ELk?LizA-B}r z4XRDp@NGQK<}>mKnDdvLD4iq}BW2YKBn$5Jc&D3RlQc^`q{)X2idrx&y?%@Iv{w@R zpiH=k0?_`&UIM&L{btXD)sQSV{dYRI=4Wa73<7{jnnqfh0hvZ!US1+xq6k2Uz>Gy8 zTM&kxioLx0+L&7^JO1bR@Tm3Mc*o0={hIYxGsc#&U8SCaal*NFmDCA?s$}QWgImA; zOaTDFKF1B^*_2e7I{~+GHyHUF8$ry?l6{y31jylL2*#7>2t2-#Pv_heL05_W#Eqk= zejV$H)Uuv?aW>mfdI2Eb`~CK+0^wYm2>+BGS23-xvbPaCw{iuo+pkowd&tg{ssWYb z-(e>U(g^+mzI@`#Ad*eUoo&v9HQ`|z_LpGM`Q$b$6YbeX$@}lrH@lqZ{}Hp(aJWDy z8tSMkarBGZ(MJGWw7&i%Ly0T^;CLRguug|EKzy5CCSSy}u}=rv^Qo&A^*E=Mi#tzLni;r=n5QC0hw$TtJ$duk#QC7$-__ z8XyJDJd}RV|Cf{STulp)oNtR`V;y$!=T508Q~_7E6_>f~PZwc1n4nd>IIPS; z`9334<%;?J2daA>)S=y@fMpij0z|Lot0tHJ5fz;-Z7dsQn;Q(~R`Jy{$9O&@Ic~mM#3cp zgbpV7f;n`O(M%*dlvJ#$Q!ESBkW6)hQ4g-_DJqo$$3X zs7=`7%A8D~)v%=UMtq}jTmHLI8rJPyVSrcL#e^AK^;(B3An?V1ruSOqd?D+nne=gG zTn}UA5@}xdRkI{+q|RLL#+C9PKp#2aChiQG$yRf4Pih0948Wq9B=or8(3w2qQyaOC zr6i0@BSHU>9+4iUfFM{?UOHM4>Dzm4SWm4Xxp0j45>x8yF$)!b*DsGiQEjqR`)HKXOFcv=R_ zm5lvZRxP2kN+V{8+5|Q6+sgxTQw>pO8vZj{TR)O~kqK&QUc`8Y) z0!KlInY_pYhrZ$G*B6g;>a*CJA#%RdqVB1wTe1QqQOj)Po1KuG^V5JZHdYohYc0~F zKKHdFIkJ!tgp%3ul%0#@9=-IT{E0VvbS#W!G$zCO!U`gsHxD8&ZX`pTZ@={%zpCJY zT>U=pHl@PC?%C@$Tn;n-p5LQSaHEcv2d08dhN)#l<*OXW6v1og!1ki~H=Jory?wKI z!H7V6pL&OX2%Qgl;(4xG1i>?CUQf$wjRtJ_Jgk%qdIsy=y`-`SkXU*0^jv{PP-cAM zOS;?{_?ntv*|sjwiP(G(uKBx|5crx9g_saQYHA>g|CTv6?cq)wZI4#^gw*6t|FxM1 z_$9Xn{?p$^uA-QY7eBk<88d+$-Ngf%Ks*3vR}WtK>i@*c-a4r~V{q@-#A?e$9RmA zBo5Vs57!n)Rj&D zq5nDB*hq!?y^J5p*Zn?4n9~&Plb8D1=Hm3}!l$1Ry9Wv#kJ~ui<%9HyG9lBYoZ$hv z$b8K7mwkXgqIFltxjulJ!FHj!>XSkD!1tr8jV?R;#2KUvIHw=YS$WKFA5fVQ>i~`j zIU#-~=&^@q;v#_kqtVa&4^N&XpQtyxbDfQ|Lp7y~GE!veBMSIFYs$w0n0^UQSb6$I zwu~Be1UR@}2c>*Ywgf?S>Yftr0kuC? z_wR!q18j&<3UHC<0uJO%Ixb^MnXqvO?r-tC1XAnGvvlP4DnT7Dhx_2@(wlo-l;s$X@n%3QG&5z?v z=m8xh!;J@X(%<-T5qfB4v5&XFilA0v!M1Z|HN&AwI} zmI3HPazeQ}R*ue|-sdzyFk`-q_1rFG6>c3ogT&xhkM$iY98b!{=EnXTasqT%JqejU zNJmW|GT|*V{H-FE*k}DJ4R({d)P|Q8a>tuWq;2@v#Mrf(32LpV>9di(m=((ScR;wj zT_t>B+)(xNCY`35vG)eRh;aFL{_$qO2?QQYKCJ;;?6y#a)I{d)g|;s0ffkX}d%d$? zo*q*7!J8o_VC;YOq3^w<{}s}66GxonKF4bbz0F&-yQSoTsp}C_ibS7ntmbR5SM>Z%Iybg{s$C7A+l?rUOH%*;5LlHg5TjrMX5sJAj((UO z+@z1}6gqw1zTHmZd7lFK)y)f!m>TM228n$#FjPG7sLYCcD>o-eB1X)3qDSIurXutq zutMnRsZk8hTkXt`5Y15?acLdKnxxAqCvJLLsRDq( zI^df#CQE`uDPEa3@-VWQVxK#o!%>qMO2mdC#s;Zp0#Y13vPdwg|XzR3RFFo{R$)ww*NM5u7hvl zdd4jU$aC?&M!3xW-Rf-LsgpBj#N6p1|C?4n{&{U2iFbkDFuAV%Q#r}_mxG_nx^7Pe z#NMr{=(wT*L&tb+d2S!~r-jChQu`)-XUy{)P04RudPV;j1qd%HA|a!@iHxoO^xe*l zfQjs7U6~(NQ1ly;djW0SN^=Jb1*p1iM)IkJ_BlT7gjQ$6$U)b{Ede5A7QsV~d!D)n zuvXR1(x)37tNB7T=!QSKAr#gp&_NDOBxqP%HWmx0zb4ie(9ZC6DSfwxqgL(}a4Y!d zyOo!)?7V_{1i}MneisPQ3dUe~rp0E>?&3ioIyhJu!#zBi?z4}_MAw-6iB&5FH5E}y zADH~pAGxFBx&4jFl|9^$x?n^EBz^NP?Y-Wg^?m`VE4rB6bl<#C2l$ZDEBJ3j!Ctyt zOuY22xyAILlj7(RDh$q^o8zsofI`i ziE{Ec=229YAINIKf>c+%!Fg!j^; zynPOBaW;KA^8wa~+Ns!I4qXl8%bYigPN0h8WE1zYw??PEfHT+k*k1iJVePx_+OsP1 z-{6x@_(xl7eY{wD1-i_EU9#W3m^EXKx(#({>YI#eKD!7*E&h7+v~yv)o` z5827naW56~`hEq=CifZMdr^|j-f3hL5&5;+hs0=M>uSYrT|;KFx_-O`b#M5kH ze?GXnGyknn^kb=Ua7ba0wM7@z2v#cdq2MD!n6tnzuQ1aeB$1`SE8CMoDEnT%cd|M% zyD-Dvx8nIGsl?2st5L&-(b<AN4v2v`&F2z#GBgXRaNb& zS>A!BgY&ZZn!M;@yX~)7B2{ui{1(&{ zsCIzlp|9k&@BCb)fEHsJse6#^NQk?r=4i-ebvYmEU|-x@0LiJcJ;ODN#Q1lHg#>{) zmROdLE%{Gt#MmwZ^EDN@f<9dfAr1^_-g2YVr!vj1%BlS;sjpkN(=^swnTx*$;b4?b z8qb@@kGtaNjo)lmdMC7()hUc{f5{b3Sr}Z2*n$07NbnX>2`2UaG7j=~lV6$EzE+V} z)M{O&#EB~ORpsUY1jje;ICEzGMT?oW^)F6rs05Qevw=0j-`)-uJhB%oyW|*j!&(Xq zAo;@I?(qR?!(p|j&Kq||U!)7esPT~MiiylHLTNvvB)$8L(632^Jc0OCX4QrWw^?6{ ziIh%fZ4ii4q&ArU$lmvZ+C%0pIquxX8@=HXNNxJ8PxMUBMG!`qkxIMHN&1J&D`EdG(q1dHh%k8en&J~8gD8Dm8>d6KcND;7T0~-dt1Hi z+z!S?D&ud^QZ%2t+(c@8Af1iwvXg z+82qp9J8}utTj4QiIg&Y{e!Zuu~8&bnc-$>#y#$uHa?^W`^h`v5bR$yrNH{4O!IJksa3F*tj*5i>GfWf+Ei3KwR3XWfFD{GfYcKKM!UpMhw6cFYZ zMqV22&3&dULTX10y4cw*$+iuY0G=n^{O=NhZ-WM zx29!MN#FZf>7(qkYuJKH=}g&GS*b0V_+yLq7t9$EJ&t(iT9fm{T&*6oHjZC+bro9% zeJUY4NzEiY!QsK(bMf*adt9cA*Tu z&90hu2_r?-F;~2#2~wB~HE(U%iQo}v~@Y>ns??k z2Vk9x7AFfU(!cHgFl6{p?skBiTp!tg_lLa0o}?VyE*}!-F4wEwxQiLR*k$mGbV{K) zNWgWznTVkdSk3*&rTcsVT%POuG%NKOV|LIV>Y=1XHY`56$RBZn?P_HQr@ng5Ws&)yQ1;pMqUZzdJ&eD*+qRtLOEm+V(b7t1k_J(}oB$&9IGT*kO zovryk&zh*e#HDKCJQ;JAz4$)E^ouCZ!mbxCeBNFB-bwCXpyn1F{i2Z~@bL@E2P<E>&~=kt^0*OQ5QX+3C|F36olX<14wGEOpvqN_%%{fj zS3}C->05s2AJ_N&6n%BG&_zg~TyTs7kRM>`_PB88OnA@hVrW%(A=vH@GpOCL)n;i< zm|hV(Z=XR_z*vH&};aB$ai#K~|NtQBd&#Dn-Ogl6!yQm7IrFdiLxam*u zj-n0EMTJ6B?*V~-Qz;89yU?mwOv`ERF}`C3i={BhuoE*Vap*B@b%Xnitak4v0Lj0=&lUf1p z1s+Q8S9|d-GH)3Sv(tZB=My@7??1Ph2DiUBx*55YPag-)xxvs9go}rZI$@^^)F)nx zrUS-MnFc|U=ij1L`b`0<*%C1`uwORJn6EWukZkeDnx$vYZNQ1vU;o1PpfGMKbO>D~ z-=v}1RXq=Jb^dpKJ!f@0s>h5Y6cE;wMs=wj0X96bd$hY5GdO+MN1E}HkB}0Ub43Q) zZ-%77`$QJVZxU#u0MPzNO7Z*A$`dLOJ|Z`ksbWgG&;fLLHYi>8ZY>NI{Wv3d;Io*| zZTGYfRtMEIc^rPO?J(#}^h@3AjG5CVQ#&;Sy&uuG|GS10HvMcH$7S2{N&W=Q(yrGp z@sbS6mV@$5^pmXeJ#v;a-AnvLSeZ-#tDy?FGabcRl-&w6i;wEY$3$`ar;>@f@$`xv zl#)Mb-|rboQaxa*VI63&34*T_!Mhp$i$D~-5( zI2X)Seq)>M8#g~EGW+RUcW#UGoerh1G7)#wa1reLiu0VY&|?p1-e~h9;l1Nd#iFyp z49B-qYbnkL!d8vuQIBJ8o8Q!?^shxF8mABFXX^3k9kI;xBi5_EtG%}k6?*fTGPa%^ zPFyd_TxPk`j!ISgD=T1Ody^C&kZ7osb54{545zR|?H%F>>aDoK@MT7k3Np|Y?QGRD zZ(_-`)3@t)mYbIHR1~TqjRC+z4{`(2+GW!FpBv{I&EQI5s_(Q&0yVYo=Fv8TUY2pX zUhe9npv^>+?1D-o6}AfmOqlE4ls3iQ+f?pHDz?z51#DT7)=*p5&O8pM?xczpOG`F6 z<`i9mcY^^j>gG;tqL#C#83Wm!hu=pw{0GIRU&S;PQjXLq#NbN-fdsuP-QPKH<ZU zy@0=3U%jgoQx_z2a&}7mTwLu0e&NEq2ni_ioJd;%#R19?8^*Bo(KX@P7m~WPwp~k_ zxVl3VMA2b?>PF4MNtDbR)aZ9Ka~7WbJlwC=_?Tr20*n^G3qY}G+>!U|4LRZIh z#q6~&5RGtJU5>^N|G5CTSP0JTfU2_p^5nr*rl9m#ZI-s9bhB3$Mz3C1Vi-9K8acB= z4)Y`-Cqp5R_UiS1(3W38p0=$$Wz$2VY@->eXYBf_hjA%204SC%-jOHWEnX-x%Wm;g zPLJnKoAE6a)T`Ae8@e##)Q+F6UU4@Ra`vwCJorU~hL;Cz?eVgk#;B-w|I0y&!NY9E zjuh?n%dS^f!G0{&?YfQEJqTDdy7-!Fh2k!o)AY2C-}2^Y?UcDQ%CvDOO{S4)Yn}Nk?o-JyY+(N|^ zR)YM&w4aYYUm8hpF9{4sato^NSW<%ns~b8*CBMA4!^tVp4wty!`!!q*x&NN-ka~k= zEmg2q(OYJpN9pWz18=sYVGG5$w&1hW+Ql&Z67wIhM*WY(ymBRwIh4xQ!MAh z03WhFmH)6lOMR!QUUVEHH~Z`n9e2+78AT#)%7%L*aFPr&S0Gr}SskS3K=sIJTzlCX zQwCmYtL7JYT)&3&fMM;4BU`rG9Y$l&Q@<_f$GvOEKOR7U{|Ed(=8*i9|LxHe{LiBg z%D@Ukl#BAf#<-#<xVIoJ5tfX;lN*imn+`doF@@^$w9nu&C(iTuu{My#}rwsNL2S zXX&@zwJ=ChIf{M`E(*Is(h1Xl&59GXmjo5XG_b#8+YXmePr1^z!9#8K>uXxV)k@M~ z1uG4mCACr!VFk}#L|u49>;1nhKyv?HUGG(qci>Lj#-U?IO+m8^hye}3h-CbRu zAFeSWTfYM&imcG(hsUmaJ3e-7STHV}V2kwdC?e_7cKXi$MP|1Zxp{LMQE})OLY?dF zY&sNY+Iu~t#ChBMFwc1FY}zTV5f5yJu5UWGPzq)MlUV?I&LtyZ3vPOk2jW*j#faCUpXnlPFg->utcgb;$4-m(tV;C?bef~IBn;V667`g4 zMlfo~%k0I*6rTtybzZk~JbBl9#mtMFy}X!jMFfcKH7na25^mHJMwP`kY9%nhNAM3= zfq%`i!EF@~KW*J_Wt(Hy(|V6K&~K)@W6tIBGe)Vc2c+ff-BV0sRK7KU6cP@9+}p-Ggx@M93Bl zG6YegXul*4(NGNzf3mgZB1KB)RJH92xHoChMIsPNwYOaBO)L0Dwh`0PFx;?AKKKcr zo;;vM-}rv*=i`Pet72pH=}bhU2ssoC<6Di?%qqYn-E?tIf(dmh^$^MVn6q9(gr^**5~Wv>YUTLAx(+-r&31ds37d3OL`m1YRwl z+O}qYS@<)=ZF+h$vmBIZ_M?=^M#lLqQ??igV{k(+~x73D;0gc`{-i7sd=8Lz~;)kN7 zmJfr^H~F4$86vJT&*gCo`s62@7R?5bl4gLoNGyw*rlCp4K~pA74RQ4mm#dUNWLD`2 z2KWZ|nSHavO^Lg(Lc5ZUz5GI*`D42Y5Xa5SE?Z^W57)toEW1a4^p4Fp^7sM`zy#K1t7Z z-hHdF^aA?kcGezfm}1ox?N^d?dd^k0-4%h8649X^F3Eh9O8?n{U=zVGavswPVL{(9 zo;`zIU0L0aL>oyzg8*4($N_g(QU@SGk#M`PXman{-Tt@vX8R&hD8a{mqb_x3!l3Y4 z3#=Zr>bvx~!<1FUosm?$i;g^I)Wnvi>P%I&TKf)JLNN*dP8IhK`>0}{%b}>~EOsL4 ztQ@|FFsf52fD*FmbrMr>z|?y%_{!+BuKW(NHJ_w#4hpVZ25*pp%1HN#XA?<14yMUUi_W* z$H)p<;pc`}63pL^d2$F6pyzCZMW5^)ZQTg`FQx`iO)O?U5+)eBb@_+Qa!kKKX;vQe zo~y`fO|y;ea3If;_KTu`bM9_)zF_}?iGj@I&H$f|lZ#WzL}(2elZwcpHm_vi8!q+u z)+n%#!;ghffcB^QTJX;D=@79AS$7(YhKIsw{Z9?-BK{N$$$ab-#9;A)-u(h zuI4ma_t9(^ldH7MLrf*I)L7sLVu5rO1=^@b-vU7A!>ZC2rGqm{DUnp)n{4_x7F8G8 zVcu0WC-Bztsvte!H6Zy^R&nih*pTWxz1X?Wek}lWa60ikIY6*)LiPnS>2i4@q*H#B0+KIm57a(l_zpA#jEt_xkHV`Fom7{ z4nqO3m&@&f7e!zVw1p2EDTIR&I5}xEm|xN~X^}9~LjP|ozxEw$eFK5^`)&1d$&W!q z(Z*Txv9YZJzs>yCcy~bRfI{!$s_|pa5$d8??E?UBe(zLJW7RF}wjF%Jmi@PZ`@*+_ zY6B+|?<6s)fs5%x;M*HQ^XjT$&KFHQ1*r@Dh0}CKxmTFq=oGSQIU%{-XoNc@bZ^oq z507mmp0klgKncU$V3(^SMIqxwjLFZM8(nU!)rR2W8>E^ePI?8;xaHxYwp%oA<6Cee zUCBi3>+uw22Jfy`V#b{$g`Fke8i;O^39}2Ut82Z##dU)gs2(pe%s!_i?}+C7sOJ)q zSaMyac#GCn=a&!5`6{8H4zAl6w=aN^pIh1}1L|?inVN$=LvTryA@$ zVB=Q7*(>KqwLb-t!pDOffjr}RljeCL2&C2f8-53w=<-Sx=3w*VT7>1X@k2|(3KaPGjjsh-8J(xvCki))n{qEi1P)G$*Y|syRf;StT3O3?gr@Wj zCK2TUz9+hESC{XO7VODWRV^(J#zTv<&V+|`k99#LPVqkt7#!MLy&djm7JD{~JN?C; zfZ2I*%JzjKt+KQ%6PAe}101rvt(2q$O&$&T-=8-~zz=esQmyi=B$f(7*bY#0TSSzF z6|V63FV(}@x&bTGW(O~ zzzM*!Zg1;7Vk3WX;UGXCkVuX>v)kT zFPYR(EQe_eGN0tbf>@vAj~g{1REp+QH$p!<&QDT?$ac%b#o%t`80@7cd81sQWtwWgRTy` zH*)uh)1h6pnhwuX<_LmN94f;PqR;9i3D1s8XJAr^0W%B+nfvqDJ7%@T{C5{6`^htc zKm`IrXf;FXXn(_y+Z$lIY%9La{YHE19gw zJT^j$9~lcrueW)uu$ha$Ifix-p&YOX9APF# zd%Hvsyn>y1j;Okc`3W7b+2WUZxRrA!`s- zahRRr!)ZI>$1**q@#(~GC*Ytm{|Sb5s|M=a&Fz}1sLrWfR9*N3Kr8-xF*{sH&&YR8K%{Cxe%-x$0xG+ewJlsv{|bGD&jAjJfov zkH&BGiPZkxiw9M7GiNTp{AT8CK5l6uCJc#7j$+-JbtKkP(@X25P<*pN67ufjbKE8TW5D`{^eJ?_jEo?k& zBdwv%W+7O?jBA?DD6jz5Xp1zl3evY4(+`mxue$2dDVASko!EWpbAu&rl|hJkqLME* zUb^dVX3nztR7dku;JCkZXp22xE<$W91nPbcC%&;W6j5FOUZ1e90H4slSl7k&CprsZ zJJ(_p$cTLJ^xQ##JW=TXXbz>5|DCdTHSn#YsiupWGkbn`i20yHTLPT&w96ICWd;LYnxHpY;ii6DbG9^uF(Yd?0^(S9Z$cJ#)Cf z#ENby=hft6WxBVikoTrxt?*L`XZ*=T7I} z8s*p(+@$~!3E0v_{gtNW#HT{Ewmse?q->tzv;t$4k=b*^_@Zr^vX0+H*i{Hev5oIl zr=*MPqc6@m2@%=plj~JDK#P>d;2M#$tDh6;E+-iZR-W6A%?sxe=vXJG!?0_SY1aV8 z=HaK}F!$fOYsGRPPv`*5rUBm$L5}dHtnT1LE$CRAH7!S!Seb^2&Kl|UlB)Cdl9TqC z>!{;kieSsfLF5D9?L*nmpXq3dJ#T&T0&kj6welJ{6z!B230Z^Lh!fKet`z|CcBRv{ z9D!3;VIw%tr!)=|wo99^zi|FK3s}v3s~HZuvLRR&t+Km3FZn5z+d}Znh61t!-DL_u zR@m5H|Ng2`!iGC4bBAx#^opAB8JY0vxV`VSKB7^`ayehx#+iR}{@ZUi8Y93M#{6}Y z-oM#9Th3>{XnQLo{7ecwfagMw9TZPFSixzFpw0>XHvqza{8wKr!p$rJxN^^tiDgE) zaOpi4xWTtd8FGq)Mno1dtJmPD4|Z z1Zb;Q=X)5Ree~;In=x!Mh-Vzv}%%!1Cq+$q&>~pMD@KuT=D81c1CsD;6!AIT!e@GmOX}o_D z(DPq31sC2R8Xr)sI^>J>qG5$v+~|Dqb?azu2Jd1`S{U0wce%=n*QdDSz*YQg`WQ25(+eBH*HYhiM4}ilUtZ%G0^w(E*L#GijJo;YAK<~}a&+PJ51tpo z-@hrKPN17-c%fW=Xzchsa0N(g0F)`>!w&a~ePkwoY3z#V@0aMR*C5eJ=&-Fa?KKIk z{7pAN`fR0&xy<#xOQguQanp_XkT&Gknu4iB-U~2L2f}?>Uplheyq?i_ovefnh{nGGmtaCbH9_*$u}4%)xN7iO+_>f)S3VMf6rnU-DNIAprn2AiEa(!SKbx&F}i8 zS$1Da@nE#etuw(#t+Me6XUFz(u5J_7#eH!1t9^VG4FNG7(LM_KZ00C{a|r3m@%m|I z5I!3}@PMHvzA1b)1qeGV>+rl}otRgBhdnbN|9TVYwPB6i_YfJ)ow+$b5%9xaPs#y@inO>twkdRn#a3<5i$F->_fSpVpIC?HO9s{A z;$-th+GP5x;m7V!jf*Uto|AzKxeX&1s@tuAV6;9NZ+x-ar$s92Ts}}0Qoe+~J}0vb z&HJ(JKlWYlg)E8?Xz#7^;;YGkOHU0+WW1;H40noIiuN? zu3B=dFWGxM)Cn?Bqifly$&MKYQ|vDrqRW<)2z{maLccbC@*~H)>fiII@}aJy}gT(y(`A+&oS4ZAsPWEMiqd9b;vc z3~o-U6_KR685y<}Zgfm^W=7w5aUBEFe|Xq%NS{P|*IXR~C7Yl5{o5n!kHMZqv6e&s zR}&P%s8$^;827fh8rFMQkGCOC$h|jHFYnEbo;%KniGC`0(1m9S5{3&IQNwae5i%TM zIeHoH%y&O`uYAsb4>OR0kA|zKF&y+967z&MReUypfqP>R+$L3=FV6-J<<~WT=SF8x z%ZCMIoqC1p3xRe#^99|NDWo;?L^+0sO6*Ha?qNeec(UoS5ys5$X(dEEB3Y>cdO43s9oakuLg&=0m5~Y* z2o7AtuXp9-s<)y-R~qQ5`xgK#tW{2eNnqP@!}TuVf_X#Y^^?XCW+1j1f&->wPB1=s zrU}7KuiI{$7G%&0;^CvdAxcdOU}tfcOo@<02t{bL7)2~VuG>dZy51X*qg)h$%&Dtn zIiFkupX)Z)+XQX2i1aIKb9*=j^0{Vl|A6miKRSJ##G&LqgbjZy=`>RnEe{ys?oBe_X;5xbfsge0ba+K6KV$Yu zA3QvX0hx@Hz;SrUaeB&Ge0rrkSn|K1fFKn}tB(XaZBP8-8&vkaz#jo3Hu^%Yp4vxi z$2UK+=uhAlzRLDbe97Yaq9%{M&p|#--qbgt!vP9H>wHw3c?mIul$iBzf<^CyD1jRP zIrvc~cD;C?(WQ;ThcBUm7+KaH>h)9>AA9Tla8s`e^joql)}(1hSLI4&a*+WGSs(e9 zg5Je2aQcG16dY`vo4fg9Za$;T69A0u5#|9}>P|Uc#%I!glx_qj zIiGGh@PCwKhp9NtS=Ag?EU&L)K8kJlJS`-T1<|8eOkvPlGeRiI%L{ei-NCgo!1;Eg zX@GC-%wy88<1e~3$;RSD%CQBML${ostX`bc)#Q2-t-$tPe<&(Ly?@o?S~>gv_eOg| zi23D^UOsxE+k|lqXWPk&wDD?y)qVuISTKJBPzg&y0Peal{O7!rVs)r-FVS^oIo(gv z1*a^`>joSk!F!U6{RtZtP}jjpkm49@zq3%RCY`)>^PjgK^`Ey+^O08VTZ#m85|8xg zXU%d=mUp8J|JPq%hU7Pgx|hH5gp87f#{q2dF2_|Bn4ii=uV6dhW#GqBC4(;3=O1Qj zZAXGc67Ha&8TzL<_zuVCofDDtUV9b$*xAG|=osBy=A^QMonm4J6d0UlD6ubA`oFsC zl>aFVT^od7sk8KT!|7hlo_}Tu(&h6bQpsg zRR|2{e0IWTQz!Z7Tv(FAAB%r_ZnXUxn32!=s{KVv2TRXC|6$pmBy`|K|@8?dDTpmME67V~pXX2!IkBd8@fj9Gl zWE%meVxSK~;BT)1uJRWF&wFa%tr$jeKQ@CiV{}#T;EE{efW4JEBJ3#aFRCJY<{yPr ze`!0krfM?Rr}He0JKtVURiRLkGBLiqsVfkF_UPAVOtS^9F+Z{_{tPxe{0z_TdA}k}r{_A&3it2oLKHZ8 zYs+2tne?yZ&_HykW^upx8a~@i-`JJ==JN+<*&&tj6u?lY0&5y@f&F_3r*?Pve3TUF zgZW0`pvJGEx7nc5d^dPXcOW0x`UEBZ3fv4+Qali#@JgswsQug7`m#GYJii};bZaTZ zWGc$I*9@6-fIX?Mg5pm8?SqGB(EjIn+{O+L6byBthovDY@BZ5FQrIz*D5t>ma^;dR z2v>{?TFUnZ)&y3p(z5UI2!7(QcW!gl*URmG90z_02ZyOxbbQOdKL|sK5h|BFtrgIH zQp;UxM+KNbbdbyTE{s%AR&*naYSF5^i7fPYy`P!yUs$8zzvENT>P5ylEBPh_Uy2S-uv#(N(*zl#dU(E?ze__FAZ|YTp`mLXquA82UYlZ@L`Q zk*)A0O4><~>N+1bQ>ll4Rq(QNc1vWyAqq&adQ21OzDg9oEzQ4+dN8gzI%N38v~gvS z7fUmxLdGm6+q&zCii^vH-R@?RxXN zEa+L`eNgA_uw+b?BQatKfbjpq2Wd0Y3TV=~{mR+0K9vWfXDm z(|d`*{0|1_=ASyL&*OTVuPxl&_D4S$F91Kq0lc@)9U{IqNN^)bzczc#GNBc3y&tsV zmYzuF@J3FrLj<016+Nz|ehP1p0Gizn<_Aw0iZ~J7eOEr`#Rx$B2$yVsr0tqd(Vg2d zI~+9oRk|>z7&Sd14t47~zkJ+#@~vYT$T!2a!74zuE;jDfDrbMr@$SN*@EXr(2T`3q z?+vfS<(oT@`b2?3!ultc&u#onu!E_9sZ#LFUWP{2&ga{I@P7E?q=cRH(uL#JifnQS z3UX>|V@F)l&UU$K`cXF4-rh!K`n9#*AHvhLrIN)5_9LAypJDXHe^H>dkPjl@tnWLO z%Qp?yy=>nz(;=GNoD0bl(G3!|R77Kg1v0*$&}AxVc4?>CI!FD`v1qmf-}$v+8NE&p z{Tx&}7x>|r#HL>`s|AH;^`gutNOU7$<(h?X@mh6KgjQNQ;V8FafeZ&7er58Pdmm(g%9Aw9PjR!C^vx~WgK@2poh7Hd3Qe_XPB?oJdl5c2^ygP*Gt*>i*- z9Dkh8B9pXE04&f2cE>^ zuAgf9cedXA3Ol>=g@`B$ zL;v4SCpTg?WgW-;4!BP=4gmHqGXPh&$046=22G_{aexG@ zW>-qu^VcTlAo!LvvKf%F|4=<|^dnbEX*=KQo;Eutr$`+du7@6QK< z_%4|;4}bQO`;XBnw8fv`y<}{dR~PgqD$Eo| zZoRaA^W$i&M4Am^WeOTF6P`THBMsYjqKG$?f3-M1u1>?W;zC3Jo@g5xKtKJluHO3s9}cD*s)v$6d+pDeeuKJ-dgK#B zIH;+^Z^OECIU|z${r$v>XZ6Kve7Nl_0#;kKWaM5S8pToFq#mm zYVy{~=OBN4^6vhgJ&mODQbLXG`~J#itZfvZUryc_QUyG|SpOf!-ozj3w*CKCNh*=7 ziFCbj_ygYF=W!m#>-9X2^L+ETf8GA>{doH6se{@hW3f|qKaD;cD6SZ%Uci*l zR}Lvp%3)+)%x9-1%GB+C@3_Lt^twgZ=fY#IjUXDQ1137Ur&>-zD_3e1YIZAry-0&! z=DzaH)WgQQ@B~`$!dSN`^y64m!~W{0$#QE#Pfm$MZ86Q=Jla3p*Q<~Ud@IJZ(fFcg z-VFunhlM>`X`xOO2|nMYx7LN)f}f^XfHv;YchiKf&p8gW-ALwU|MA?@aevHdBUJ>Q z>9gKEr(oYmt=R~y5NCmTi>FA5Gk}ZRy(>uGd%G?x(2|VNmx}fkGMfKy*rd{4 z={&%4KYabP_Z1l?IK;6(+h0OXvKY~S=gf8}3SG8_Z@6epYJSU`S7}6jr61t-z`ikc z2k$XK+2!Xd{NudW9r~njm*M;LbA&fPlC{n5m4YwdxRj|H`Ti_}&Fz#zx>NoRTAoU; z3T^BWm=T&4a(%0hiBedPDZR;w$6YNF^|zYy<)egn^DC1=RGf4D2dh4L1VzwnyxWCkGd>5WoHT} z-m5OkrMaeIQ(Ik)*g12`fZ9-6RpW!hQAvU0i_0E7sB@?!!JMxHJcLQp+=3MuofyT^ zbpHHBoz>y$z_q|N$%Q)uPAb6jIF_y*iRiV;vr49H^1Muh!W}+-zl2$Pp((<&DAu zHJ&h!JLKc3vfNpRIvMXbUpE%ZD8otLkx7w6lZ&A9uNJgXDbjE3Pv~8Qx*{c~b>|4R z1Hc#N8)#B;-lm(-fZWNnd!ZvOicxoIJ34lqp`lKT9Es1bf}JLYQ_GdzXGbbVtb)(^ zg)MfT==ML+JNgYOzgX(E4+P)#mxXzgOaIT0!2PlC=S6^T7AK5Cxe^!VFFMFEJd&-$ zmjW4;7$8lLhE|-W=^Y!oRlr1f^4OKaz|6y@U+Q>?GHq8y@pK+I@l5;8kJK}zPfY;= z)?{n$@@}v4VVxCQht{>*&{ua(O3wfB*ydfwYx{wV4mY{c@WNB}-7oK7J@;&`@$r|F z4;H6&JDN~vhdUyz#UJ(nD&+51J{(Y~zpQ|6?0SGg3g~ZQqAo7^b(qOd)@=*`6tQ1X z%IoYk+ZVh2^P>C_r?&+4?6fnl)0icZ%y2d8E4snY+I%P0ooEIN%hTVgP5CoYXYS9g znm{;KJWk$YQ>-Sj)om6=8@@BsRI|v~k@!nTAB`H?% z(jqKF?Y8`{&h@1F$DV`P183z7K))8O*C-o8oF8zZfGR5+&l^mp7R?@jQ;{vzDgLZ6 zfk*bU3z{%HEqzAmZca|0jowbveB@ilvSHqrVnc6@{mD|DUjs9;bIhjs6eI z#l3L}&2=c8te|>NBhm5-H-q0;KhScLEHz(Txf!N;mgaIo%J@hIrT$SNg*4AXq$rLQ zhj99xF*Mdn{ioeo37eDQ%F;|$cfS7O`gDWl^cMN@pU)&q zAKbep$Y=lM70l&ogdR~wtRpHF;@FSYH?$bC z5cREm&d<+o`^~&6w7Bv7FUky?ZI@tD3KI*$g=yMB>m~~n_qaf}ekqT4t~>{V^fVO} z8W|2Wsj929V13!j_jO)%4Yp+SY(5QF^+YVu%y_%X{l(A<`{b^;l7XC(fuo2{M1j2L zC?feZN+3>MRcAt}(u<_f2`$qX9a_|JoLEVc;k7IhFIEicm#K~2$sXTA^TYGhSrh#xjE?k)CA)^kMHq;RSS)z# zRE8HfXB(w{vanp&y~t`mC$d>t6mhyqiNcu8;wME?_>&IhIEWA3m%Iu;fa{PUzSGT* z^?XYrBOSJ$v9PfiDDqQ%@Ej(kySHnkwL@3EY!{lZbSAbIM=W<`Igb!P;F5sN#@LFq z@!D$VRMF|O9*xaKYv#P<&;)R)ZwT^CjQ4jrn%{nZoIJfTk)Wzd;sl*nDIF=53%9<= z*4`*9d>(A8LA8IkX&}p7#^3Z=ERB&%hc|JUI^0to)^KptC7MCmpO_gXs_9kVj)V-2 zdbuuR5QT%VuLD!0$GO$Jh#gK4UTH`~#@aoIVY$B@C5ZRA-){4mO;R)TvBqnxdP`kI ztX4XQgt$#y9%+ZNQ@(mv>XL?yzMiLWQiW5JxtbxHB)*JTDW({5WTk@@3j)T)4rCHL z60?Q&;S0r&4=}peK`dW6OK#2;!`<@w`l9u)CY`2qBx!s${h;9$Z}Gxm`*ov5w{)L1PYjVzSnka`VG2G9=O!y~K1`j> z@!xwEL~qIpYdt;Qv!@1p7xh1W-wYt22u7L=%}8nwK1Cqjy6keh!yx=^#%K-ynd`kC z1UnyLhYFq8d-HR61xp1*@0rQvi3km$i*5Dd6+{`OiS>%40rhSb0fcFu5`v6R=tk=b zaXZyq(HQ$$#+c}`gA!;oxwA765n)#Xhx^&H!=GWh;U@exdI!LLT36v&u`PTO5h`8q z2+aq*bHvh>rwb~eRIum4v(h%5x*kvy1GPLmGfec*S>j?YUSMqj?r}!u$ZCzGwGL2AX!%;WF9v2f1Qnf1|h~hmOesFjN zhk;>mZhMR_LXl-Ydv7bTQywEFE3l;&{i%KG)`${0FxCP;>k8sptEjA-Wk+B_8bCbx zM*O6ohmB16;U83m@jMxbgb4M((&FTXJ&Vz5pX$Eqjh_$dqt$p}=r%hYguEW!jJqzC zE-nYJm}9SWXZ`wi!(4ZAFt>46P)l9$z8!EMMW^Nw)1vvaiH5O4${A^+p5UB;Dcqkf zU!n2VIk7_pksN(bRNh%H-lo$&+1nR^EMYvQhkT22+`ymN%yl^6;kI1zILJM1;;=Pg z{`_q`F@D{Q3x-aq_R97|%S#;<-4MnE%t-BpJadQcW+X;21^tnyH4q$4n>s4hJ~p2j zfwbN*VTCOSy&OxK|7NWtf95~Jf`-Q9V#2)>cSkO~{xRV^IyN8j@EPZAxyu(2U)xct z1NVXtes(%=r@9J_KbOYq8uj3gNYPuLtW4y+7t@@h;a1Fj-@k}Pb`--?Edo?ABh<8o zwPmXmQch|(T-Go`RFQYc?)y_|HqfN@Z8k`^R(w7xUh5X9-0oVQU0hy@x*d9}VS$_%d&T;-^1G34RTz%??{Vg=PLw#rp8o$R8Qut3EcEny;f~)gB+qw|j$Y zx!P=FUDpJ_LBgi8fi8Qi+WqG1?c{tjos5PRRcDSh${ICMe%OiqrC5fdWtyg2bIcD9 zqfbAs85TXd(`l%ZCDN`v=F&2ZDf{X@o3HPkUGg|!XUktoQie-f$#c28^NncMtOFD6 zcxp_+g_x-{QgB=-vjb+tV$vM5L988jj?FTVJ%iz(MR{_)Ja{?=tuf+lMtbf^nlK1E zdZbe`9Jd;>PvCD;Atlpux^WXb*wxx3og?m6q)n!yi>TlXWD;V#*DRjcQI1TQyUx`l zPgv+diXk!Un7u&6Z6(HHWhE*@D7J~OHxrMvCc_I=ALhP{;hx){{e9sRRE!U4XntMx z`MEQDn~~=%)(-T%qs?%3s`Jcy(#1#h>ut4W$(RAx_23*+BqA!aU)wfD)JqRv^vHEj z4RMR$Q`^0r8H&;}R4JWCj%J3IYG2J0EY7c)&gyN-WRl5wJ!=-{5^!bX!M1K@QQdmIEKIJ_CFR z>`?dS*RHy`!u6_rpQZ~@2HwJYse)~zti4a4yPBw!-Q}bg)=>$lZ&*jxei>SFtK?(O zH`Z);zWl+>bxo}TGg)(~Ejc0N37RicgEm#Gkz1=B)P8@?uH*9)NTGIj(yel{uhILm zZm#adA@-#2M5R7Q8JPi^!CZrT2@c+zFLRs;QBGE>hv=f>RGnmBvA`+6_U6$ii0x(b zyDu`DQS4eLwbvT$E)@#OR5LcDo!-nnKP-Hm#kVEGq*|$T|I;qM1@}I4tMl1+Six>h zA?%49?8x2q^WClDsW$7EKnmFN))aqoa5^@MukSWpcLfp$y?WxtZ^=NnF|qg=&95=z zol4zMRet;o=!qJB*2AKsu(WM{Vmt2_QR-(%YYegu-(%aRi@~X8j|(DR5;spF7WNb; z_j*F{{P)F$Efbzd_6P#^r?G1stWLb<8|Zg@)85kp(Hd-4=}L#^M^x{4UMdtAP)5L2 zlivD|&iWweTt^QDBqR6(MQiEor^_qg)d@1%-CY><=9*eFXQaE7Ur&LzVs24EkFTM{ zh}?()$L_n283Deb`1eVOfvlB1trycw^)`ERgv#!+F~mL<3$w1Tu9(71x4|~);0mQ6 z*h*#98Q?l6V6LB3OzKnPifk@#jm_+jvDb z9`RjLRPuvzG|Z;*%0tTGuF?3x8k z?rkj`v=kF-5pG|mgJ_lw%aGb6t=y2-%y=!*haIV*CqvJ`k|_uI%XQ(Y=zW)yOV_B} z)wr*y0K2VR^-C{v62Phn-wgSq0l{Ftr&uryUC$egt#7MdI-O9I9(%~-QiweIwXkf< z^kWHE8kBNXhkDm#21@m(61V@0U>FFeXZ^N4YAxZw>G-g5J7^FddoL6o_4Z?4r>OPC zn`oV+o(Ym|G<#2l zA`hO=!1p-Lnqj$gN%H-J>ylO-eAu}X6+w15NnMLi@>awXe!jk^Cv7gidUUCvm2b>= zCj5pb z>yI_p#ohm>?svBV>$=))-1XUID!Jvei_NHFaZ4%&-?v1JZfW+u$vh*1I(1_<32&;;U|Mk4h7IcbNja zG6=QLG_%}ZXV26hjX+nZW?6`-6$MPT+xksB$?sCj6o>=dQtGKd4b5Lp8Znbz4{y!C z-P(JAo1|}3znTLntm3Gr1Xp%X_yj!))syJ*t&DRYnvYXQH^6(jMW+8#+7lpb;5I#vyLctZMe3fUb~d zSN%iIp6d0ud2pDl1{|IFkKZ@8hqUKtB7ziCV&PlNi+Z8GnVe-eGSBfAgsXEC4-|k? zR(svhZ#@Gkra#pSwFTd3JYNEvwjQ!IrxmArn9&i9OM@0`Uz z7H#=XJ!nsB_>xLW=u60%^)s<&B=R)mUG-E-@lh0InpC9`P#3UjWPF``_jkR{y+kmw zU^*!o<6^%s*B;=-i5}#Y zA0Fi$S_F`s7uc;xkptO}wkD#&TlwOmW3qiymDK&7NGBi&4o;2)s`mm#{h3SP;Uw&^ zKUt=MJYVc)Rp(Q!AVw1$`EXs6EzVB3kTK^C<0oAxo+5H*zp8x0Qa{?z!u|HHfyHeL zX)|;8iy<}2` z@u*xkpc;^U*S*DRJ}%KhCiTme4#9~91~@kv8StR)D+wetU$I(NE z;hxm_1G)qripTP&fcnTr=+tI*!hE)wdj>NzbM6>(9OZ(-T1OjuNAx4r12JJWb~V21 zC-Q!5G;uIT@Cj)a!v;prGf^;1SAB8212Wx4%T2(L?F+&5k2m=iRE>LD2DTFyk^;oz z!gtIF)U6iHZp~PPv#3?wVD#+%<+F#7gz8);;iNZ-@eC&o^)zO5B%>2ND~gcP5dfXi z80Sidr{wLg5?@#S3?qKvPk2`PQ<7azGbcDwH*_9Qu&tf#!%h1GAO~CR=JeCd&RZD* ze>hwMERbsAa+l~(eswJ($`XXHd4YrZKxg~Uj3i@@MCJDVZZd$HJR}+9xAh#T^&U4< z59Dr|GR2<$ZTap-hu=H#bg+sOWaj+EuK1ZmQbMSNA$#z%MZZ}5TFgHr)TlJDaG`{7i)+&usJ3KYUOA7H*Kw$6?0i9b4 zdTbh>dO>#$B|CH8q@o3}1E)%S&gG?skHl>o8%Vheie0#m0KCtxeFMLJNs208Qfo0+ z#MrBqlsA6ys;Clv&x{ce4I7UZk9M-N&^-l!n-45!W?^>h5pLBLl_h=wds?bP>1D>_ zy9cAo8R73IOiVV@5b6-NQG~pdpG!zlS$(x{mLn?KpzX>hIoE(&_J^0}nwze?IQ$+` zI4Eo3ShhYMbx7Ht31uQs$BmDC7d5P23O&26;l2OJ3ngeX>Z2=l`AsU`L{{TKSCZL# z6!_fIZMMzP-~^SHnW1W`$D_Q~R27uT(&b#|VmzeJ=Ufr5+?{TlUY|$!Mm#cA1XFQmWq{&V!K7UcP`*OBvO1cHjQgxwuaGK=fqK$UWo|v95wM-8u-9aZMwR6^@~d7Jz9RnrDmP4*&Y_+PUCs3*gnZ?W6`H`A^sD3^u{CrvkFT`qIH zOPc$Y)$7r*bS-5^X)pQe;a;2b?kE-^8+>SXYbYO?G=u6&e3U5D&0V_|7C1SK1QCtE z);5#VU8;JTf`N?k&33|hSxpR0`6v?xCqRp-fh2@%N*DxRM@GuBNEk>!ZNv~VPJHYF zad|CH?C?kfO_*S!jv2R#zvB)^f%hnDn-73|?6qFkH+n|BVYz}-o_A{D0hc^Mc%l!d zMA+lXcPB^lIHgWWe+Oy_Hrqv-i{uvSs(b9_lA!Cty!sD*X z=N2vgY7Q;muHdx+YuSLJ9JpVf7mkiHgs3E>$;&0VY~}u#+c)sJeHv6- z**zE^S_HD!p+c(lj|}w?sUFNhmGws@0AwI*eukeP-Yv%Gil9$qZ%{eGA zaHYGsE6Rl5K1Zhx-jbw!(s0{mfgdip?A5lMK!G-9T+wpX%Dta6aIeM3?#c2{xyP2B z|MLL!r3iJ=^U8;opS)DxN!gG1J`b)|TC5?}$Y$~BqoY7>@`?ghiPu$8MukaCl#e2t zkO56x-CfCA5Kgh2`ims4G&=wmdMqKuW*{Xcp|{<>qs!JOLZhAY(q6BGUwL!GOOU9> z^^!3ZdulT`FF&X6IC@eU@6W7C^Xl9xS3YpyW0}?M0|B>}=aY;fPLk_JzPUn(fQj{x zVB7gV+~{cCP89=YG0ALe8eqOlS^JWV74SlVO3dF?qoR|1k7;Bl^lW-TpSj`ZQnk0b z+E9957*7?7Fo?2|gJju!F1~ehHxCL5-0nXLn5p5Yb6WV>PDDrPupwTe70jHu53z~M zgT`jv-AqJ2O(z zsKIy#EPupam&l`v)YCzDAFMTfYHOfaG%?+{&+eRq*EP$XvG9JkkZHnz?^$o%Ayc`v z%J`lh6-f5n=SrNo;iB;5*$48fs{CGj2HS1UYNN!}E-ijNxsHrj+8n{qL2OjGOx&LR zNI-2NrGrNk;O%RM8C1C};if~8%Pnv^)Qn+z_;zT|lP<0JLvcCx3w*u&Yh@xdJk7{E zLFtp=(0v0??fO?&bycBQ#<jI=h5MnhAi3=_s?X-_RaTaW{`}~vi0l)2 zsRpI8lpzpVv)EP|@6A8qtpp#t5&teI^oDlvtBX5xA)sG=}xnl*dZ9FNaGPKjm(}LPwN3PNfVNom(kQ+!NbH zdtwY$Dzr?!+j2kM=$DNto{{3#8RKql%Cyunzr+r;`ngk-;bB#~xPIypg|oo`#G zJmDsO=aeC*#UUr)$O9AB*D-0VT&-EwPr2S9Nr%7Cu*%<7;NB(H6EqpJigT3PpM_1g zn3H(7WiinnrgJ~~LE0C3k#L9T6o^iD}fW*|Jif3DXlq#H*Wd+YKuNlkB^PZ9$iKrp$ zwJ&5x=Z&wl&Fk}L_y1J?;-Z743@nQAR;(L9v4b6c6Xi?&ux+ zg$gf!HM8z1(qyYS)XywPO?9Qs+?_zScebtfJ1y2^5cjSnv`v_+Ax_aq6C9`^^u6O3 zwQpK+Zm^}@Hd#c>!uew8@>4UxOmsWt#;70a8r7%Kv_<4jiF#LhgsemXC`Y%hL^_xZ zi^%NPd`9kesMpzEPr~Ae<7ox4!2?|!!EH_X2$BY}{wbd0u2||hQ_yJ;279Va4u9&@ zZ>xdj2KK`Xr>&BaD#rlT6%9?LOWkdzZ~w>(2hgaSySw>*JUlqt6xq;My`(bzs$e)% zf8KCttcwZ$gH$zQnXJ6;=*S?P6Yzm^@L9rR0s7s!dkknNVH29=An9xgGjpzB`^{X& z*NQUo)q3Sm&n*o_+{@+iH8I0ExVx|W1Wp}#m2>T?W`C})ntq;Up%+ok3eOkWH70g+ z+ZR`q^nC`IS?IBO_n5Fo(|&9aKiCI{?9EsoW~3pa(SG%-S+{ao?j7=3u;9~@A30;Z z$y+VmV|&lr{N0_sJ~xbr4h{N`){>u$kY1FMdMhjB4-ctdD0jPGGwJxgSf_Po{H`1K zU=1l-1rvD>9=JA`E`J4*lbQOa^ZI6PmQ`^O8Q;G@5TU{T>fuo9gk}y#+x3`Nvd^g zAMAZPX3HKUD3PDNXm|R=k`!~Xs$Q0N)cNdM%foe!tiBsj29tN<8g4n_Ms8JB8WTSS z6n>!8MT93lLYJ176S7$(l^*4U?n&2fCLa-x2v)IQG08^@un^UJBd<(8MREOQzk||S z$ra9pM!E+j5t>Q}wT=;<@hOSj+FP|NOhLhz?fp>ahLPH_6M0!D7B=A7mC9bY_tmg? zoZJqzuaP2O2kS?2>y(sVqiW^Aa{6+^Q#7Ya`Dvv*+a=()43{;_^Jmv1Gq;=tGZ4gr zz}f;#t=IG`Y*h3_j`b>!4xRz%kYz%Zb{KG-VaOzG(}ehU!DAx zC@Jok)dnPwN&+I!N!X{zu_K&YjM!mu@pjbN1}pC*@ipDyYE8c^3Ih{`h^qg zFdM&!d(P#lQVWa1Q*wkT4i3NBL#5sP&Xwe3vmQAsv1AK~nA&o^N}&7olJ!C%zk?TF!xWb6>@ZT8-WGlP{5BF&uhcFlnU#v&Ogs zcB5~t!dRT(I(3A&u=2d<6%E8rc11Ec=~)Y2rT0|Avw=h9gezjO^*09hv<<@&z=k5# z!3Y83#*ZDW3zviZ?tnShC&B4llbg{=2y|L%s>MOMsqGrfL#)P;>~B&zIYF6?iVfL5 z8k?*ktM9*iAJVoB9Jid7Jdy?PO1{58JF)i_!^`){;2snA(!TfaFW&eH^9>qv|1fP6 z;JW}o*W+Z&`TIg|KavPcF>P&>7k=AYm9+>8EKkaw!yHoM*;S&d2MO@ZmOhkU%p|x~ z`u{PR6&XG-U420?ZTU7%lj?UdR6YTOV@XtINL2|Ip5C6|3wLw_!Z)!b#W z6;Lfvzh48?RQHE^B(^)#n2!Kt1{Ybr_*FR!cx1NqL+h9DSU|-nMZLym-T*8nNuyPrp2GKG|AVt;UT!MU>16 zxi_r*++4w}XZ9B+=zKfer|NjGJeb^Ddyu(oI2aYFE9mW%-Wnjtm!xyJGurT4cCbsU zG_0MOdm4vS-jEB|1SFQTlAS`xo|Z4Zyx8Q=N7-f6c3mq|6HEL&%--7bV^EN1$wc0V za!BFBE8X_wAAalO;Ep}rqi?tD*Xvf2@I8AvelTbyZfbnRy~usXNX&A%)$?wZQgq8( zFQ|6`Z^Ls!$tmL73u|nhMhWYPjRuW(AMG)D_&vHb9l;ROgW$5cHLV$4Hb4{VbeU&M z2L_gVuDUH|DhLwB+9+WaGGakb0cC#3Pedg2-IGk}dr^uEoVfL(7KJOM!r7$H0?$v zA(ebd2}sM)iHT(^!fbT~4}wV2XH)1ruA-z zShL!KBVS*>XLuNkcynR{4RY~@HM-lSn9P@ zCgn2{OI;KBE3rWPOEKGP*ANKrF017VqEi19Za*@w75JjKT7PM=VRmPmk|&4AZ#_^{=Ami zGnLebN0K(Y`&oN4ft#0347Q4#DgF&z)4b5RcJlPgf?G#^PeOe;UoDKN8Ys2BMUifR z04)+`pxmOG?SSvH0Gl9F1JlqtK=9+%eU(PXtPX8)>x6K$v7W(@Y=nH6ghL~wcNG$$ zyxD9*txaIM*OZTJ+BeV|?8*dDeTpD*Mo7yb=X{8NC_k=nW)e;)-;)8?koW768%lfA zW{sE5tY{>F+q5ZNYA8}W@Zge17SpxAiPmr449E2(I86I=cSabqLx}uR7QN4ev!0v6 z8Jk{H+vf|-yOl=)+48#vwlR{{6(cJZ)V%82t($s;{BRCK13huHrHV+@y;#=JORsI> zBL=`t``%UTlE*1!F#fQ%%GQ5vd%9!T|P7oN_adO*#ID{y=@i}n5c{iXY`P^lCM|(R; zrtX-e$m40d$g_yyo-q0DLiZd4<@&rAY*IFl?>^I2qCzCv`5qg)b{#z}SK4+n^n2dF zHWNa;axC>d0%vFBE{B}aW~4&_Ge!%cSh74Xtd;Lf4s3zwzk&X3_q<#b0mOdQ9yfdF zJIxTjr7EC7L3?3jdVTT1zz#h`#}al}kPFqFC=`>I!qWy#9CCLAU?pBYH{qB znz^$Tri}S3uV21!Y}Ie?h@_rOJuY(p#j0a%fz9qg=s1cVe#-L@1q{mZ zzK)5y7iD=XQn^VZ>r$fdya9CmpxQKePc+js&4Ww{DW;SRuZgpng_?cO35UsG+?Y+6c-`?xDZTjPQ9A`{BCwzy?Stpf&ONZJ8 zW^C$JfB2yHJ7<|haFE+(&G?i_(ICvF|7^;rQE~0jnZn6(Y$PyOP?wh)8KAezXJbP9 zh#~S-9F31YSENq$ zaO*E7Ad0s+`SL?lf*|bRb@0_X;olzem;YOOR+O6BaTTR3wch|x;qodXDWt!6!|~lN|UqFJFWu)bHX}h+_qg3{Ge+A-&w=D%}2jC~O*fG4dT$_ZrdsDKKL{ zC~`E>Pd{qDl_4kT?MTkIS$LFqpzpf8KmI9?JQh(aiK)Pp?$vg3tQ|qy3F;3|b(43n zo{dmyIWVpx*hF9EAos%Xw`cyg&2?N?58t0xR(&Ys`))v?NkI6?)*lX3PbFZKgGYxi z(JR~10vO2>H(VLO+{m0iyV#5OHG>U}nH}De#OX7Oqm#7G7>b8FqMCf!VRzVe_zY*{&ZSuS$=4&XM`P^u>! z`T#wD_LM?0WDsBH_Gd zWnC?#i04jppHVHM9_PGXcog+l{RGyX!}uB%RH|syfbd->)F3{P`?K*wg}m8 z0{YaqE=?5Q;ey!@$Zu;Z?TbX-Z)!&heqy;-N?82clthztoF+%tBbrfah;#B{C%bh| zM|+Jk#(S067zw^t)PZ{177!WU-bsRR9pHqDE&o zh*3E(`@`#0+TYe#?YN+0c}N&M*XJfj6v4SqKb?YpFNiS07tWGVp+)Afq|trEQ~Iex>{^EV8Xw*f%ij+#B$OMcUPqY^<@ z%GOVF6G1f0iUOhs+kTr<^l7(cUnw>m)a z$w!UK+eVGl|4Nkf)?D`$lUMw!Tvk5!-u4SbP`rUe1U%4CRG#i@UBD0EokPEg1-pZ) zuG0nEKcP-ZmdD+47mHRJXbT-lPmyIYkcjFS!e4QUuJ)_V+xeL6&UsAT4Giz4c`bDg8Bt&E3S-^>yzmW%FYfzGg**(o>nQ1m}4=8n37a)PAL zk3f0WW+dNi4vcYDS3*xR3ZP-t`u-J4<@?S++0>4oc+gTSIqpty5B4FE0TJg3zWP_$ zTnVB{MFPvcE6Mw6p{YM;AC9T48u@L#za`v1-dMcd$2a0rduG8W)YF9KLc2-cv-ct!7QOP}VA?M|uDuNBREgP5{%} zzZ`}httsnkKw_5sc!fvuH6wp}ZND7<%12gVEvV^uB)z;Co#;8`Cg1(T7KuD`dL1&jkG-HpE(0UtOikFG`o71poI4REWJSAU5hoVB z`d7>^aK=gy0kabO?U|9iUIX7bahb zIHNKo#C+@{^r8pyQOXQxlQ}g8`S#|01Ah2E{2|iD37GJR1019sb6&x4?4(H{cB)XU z#ucy^Rm5+52XC2Nij?+Hb8DwBBYNRTvYZ%AH(<*4CB=UJJwx#@JYMO@zr2NPyCkpg zRe_U0$`t!)&zX^uh^3+7AZn;6Ly(c^gltLipkQD$&I0Wg(toy@G6k;K8-an>%13|@ z1vpBk&Oc`pfe5|EdI3u%T_&4QE!9t9;}#eC+m3BUO5O#&$KKgq1QpkSX&yZYb^2Jq zHDF4q(~0Mau%52iI)SF!lIde|VjJ8XuUe~d=Y=AGG5cSJzwvmQ7j(x@-YVAt>Gg2R z1;AOOKI>~B&091oWt+PWCh1@{k_&d>R_ZYKbe-bygQ(%DWvet3Gav<--T|iK8FF4R zj+l_!A&=$k4xo2-B>|t2a?&YDn*uo&Z3m4-uvRzHt85-9Uqq(f@vh^z0z z7@MjWH)Fut%no`qTw+R-)St{1}eAhY}@*=%|}|EDwtOk?sPxwwyLq2to% zeAIccMO+^px3q|xUQCMxmpURy0=z*nW{aovk>eo%i}@R3@J;eP;3hmE$2rJrFdsF` zcbpG(PInJqHk0*TVe0BZ1|Yq&uLvCvAp4DVcLxR#>ec=iaL^*Hfso|hCxYdk(R%dn;L=& zCnWrhn=n6i;551rDvt5Our+O}6~|k^Cck0_FidFwDFbCh)I>kLcIpW-3zaX*+N~q<5|hIr$Ma4;}~|0C#s~$6Bxh&Cyho53NWsVdF(W ztzoVv3WLR1s8^c0o|^({4F(iM7<4LZMC_kx?cK_48lK8Geb6dK031N~SE*XRh2l5w zlYp7{)h_EI?67zD{XHRVy6!WmS;03Cs|noU%0Lj}6Gm{GNsnBYp##X9_7ymQY?M`3 z9#r!68v;fmC)4tu;mBg!3w5TK_x!hb{AW%wh;s^FXx2@>wQI%JckrgZWpZx{Ct~&D zmu?NAe&HWw5z6TmleRA>c9KViG;nV3?^ptj`7tx4(QN^y8ORXe533>JphpWhit?vO zX$9EiC;*!S+#%??Ai(gF&Lf7`6cGyxBS12;gk&5_EG5MLseRV9=;!X{Kw-4|BjSHhG`a=ap^YYg87fz7* z7K`$>go6g-!;hq!A5{~Sn|eWtClgslCignJ6EZ$?ODi~FQxuSEx%|}&fLwE~NHc>~ zk@tgnV`nYzdhs_2fU70JyQNE;RT>|yA9ED}|NW7P`4!}a->T#{&c9wV;R~RDw~zJE zMyZ3mLm%X^@fY2E-EJNQ&&l&4pUhqBth+oT!^7c(9fj^#X<%sUI$Du!Gt)_US#>BX z{2B97oK0^5&+8akRKg5)+7xJO%N_e%8zZ-_^cN5E`(G5Gd$h*PDhJ4OW7%iGV`I3f zW1D+PXC<8#c9s2AfSfEz((Jz&O7q#j;xZX{K5Kfkmj@cE#~?38D|#Bk+wMTmrSrM0 zx}~%dI7Jx@V@Ym> zS#1^WuxEIz`gmd=rt%PcM1IrbIdJ#zjuNeCBzX3hi z-V=7cne?Fd|L_t(cqZhozaZ>%MfeqX3kf3baT6PQ0dB3188_9jeaymE3=qrUOF?K| z=>jDN@Br~)Q&X-2T{&4wMyeBB33~s3qVpfe&w7C4XZFXkZFJnE9y&jB%IeRF7{Ez% zeb*MB6$*LR2-PFQku*-WNq;MQP2K?senX3s<8>rMuFt!VImd-Do=JH-wiMafhMMNr zznSQqcsw0*zffYklg||H!8jRGNg3&`AHsmPwb?fLgwb3~xvwMn^_C3N&jrlk|H*>+ zm|1|j=!TZ?p5f4(AHzne`+x8G>#&q40N;ua>UG@bZoJd{yTekJ%)bTYOX$txeI$to zqLS~^ab>hOxL>+R`sv;O=ATr<3201B54x_47&{fG`JA+`m|9sqQucNyAR+%0a1`K( zA73vNM5pNWpXjZH_oi{~R1tbR;W@yOm1>`prei^VBO?M;F#zcJ|E1qVj`eyK*FVS` z{b0MplHAR|K*za?zj|^tKu>O9-CGY|am+c$_j0Q#AKd~M12dNs=pl8Hsd=qnGzPP!Wy^=xMJrNK#3KvRXYoPVv%nO-~JMTBrTF~Sa*eS-oKfQ zdZBZyfz7qUT2Ll=H}A+FYq*6^*xSb~FkEMdF+WErTK@QKVXTaO4CcX5x3>H%0CI#4 zPaW_!Q+gf(ROXm*qs4liQbjM;rk2h* z;Bd#kl-qwPO&PYw327wqe-n}tooFf@(6VZ}2AX)@YQKI##F|ndwN&bvz?)kgrp3Foa0=Q3722`ISx_ z2I?O8Okkn}Xuyq@^^otl%>c6~Ty$AVl@zkl_TS8+eDh{M796JDPZ+qwND(MCID@J1 z3vuw}vfFePcYRkn?H7szk-#LxvA3XBj&&Cv>$tXm*Kz-BRQ>b}VvxW4-kf}s&&KUy zaHQj3nAK)RORGghcqGTYNNQpIxmdvFA8kiJdlu%IimXER(@4(OjzhB@IlY6;r1vrZ zXFfW`Ve>Z~Oq#nK$2z^pkOcb#bfti{j|FI663nynr5y!uIgP9t^SPv+sojL#d{Slp z^3E~b2qCVU0&rvQaMD$8SNNC?4=6GMt!9XZcBD zykc^gy1**}4q4Bwiw)j4`Z6cv$F5BR8W*NzZzUME&5w6E|?Klil?{VJWJ-7!M}uDIQfV$ z*&Ss8<@vUWlOy)n*~fzfyUo%b7YOvC&VQV_UvkCw<9)W8yl_^n5~{Xop*w5#>&G?v zH*T=fveouK5h?#OM*=RWeW$%{Dlj&x3xAhby_lZXoQ1bj;(hU=N6~w+uFKxYDr6|y z5oH#5$lA*!ZmOc9r+Y;9IOkxPXb5=*G1QxUku&;MF$}muQ{hO9wPh{le9W+MF(zQT zUItcL@zqDPUhiwaBSL!K&-drt1HBrTSgyF2<^6qvyOaSk_Ol z^{59A>A6czXMgn^Ktn0%)XRVTpG=YhSnH<>aQ4ugTS)pb_E71!C~aj2dA71C86+zF z0TW{X`&4ik?D2>CPZr|0xfrQ6U&)PFI_D9rTPteFj)AL0?t%~B$>_XD^w`}7W*EC( z%YxY<~;ogC+k5Ze%{#5y`MXM)wiNm-|u3GJ@4$`Ml{u^=*`zBnl1(tjN zUmMpNmSnbt(b76IrZJi|Ory_OkC(LRQBWI0(7a70dVJCt^{9=O!111y76_>)O%0hD zj~6tB$q7b9yr6dRQjM9DqEKYsgGR*=3U44N!ugzE(sTZN|GvG}Ui)2pt+n5^cSBjJ zxgL*vqH@br_BvhIVLT*T?2NU_2`cguc#=;I%A&#Gmr|aRauBJ0t@)!z?i<3*fa_A5 zTa*g}?S16|y-yV#2ig?Vb~C(I*^rDXOkbpGx$Kl=1g5sW{@l6pCe6C0lNs~1>6={= zO6;X&%%l58w4@T`$|7{n8Q?=g>jeid0LWuK43rW10L8V_HkZ+YAx^pOYjZGev{cH3 zq{Uy&dBfacQlr$UzWz~HONZtapvS09Y{fHrm~Uv`7Pf?xh38rI_6sVg&HCqf)2w@s z6W-zdLg4%>o#gg8q*Kkt+A%acrpM#z_>zi~u#SNc#QpA2b^7a6UctOP@8-1A+PZB7SjH!Alf%(k(q8WG&C6CJWseht?Wn%vV{0i9khei$ijK!(RW zyyRiyAF>6R&=+$HW`3bzVDOww)59AclH=L-g8`jv)*q)GIVaZh&zf!~_<33r30>Q#naTu;`tY#9?O6n+>tKMcVAxOz=md zNK|*%-dc7&``!5&MX7W@$#v|9@Ic0mH~6#}pD-?$Yh5$BBI0zv%Ryw^;<#Tv7n&L2J872hWsv2+l*J zy7Nl&>FTsdlgc0)GIji6R6d19xSmXu3&4Ge{U=x{tfsEkt~S+aR|u=P`}=WP#?ibu2Wb!vA)#L3Jj- z`0;jv{z%)f`qR`+WXKedMc5c3zRhDdHllt&jMz>cO z`CE2VG#+;ix5NX3KgXM8;jSjjGm7pW=PU4ENgGIAD&c)1F-!8-h9oNvu4OT=h#k!k zlS+?+jj;qnY}Tfx#=L1%VY=NSQ-EKKh*uq*v4T*(%X1$ddpC^s*~B2b8gb@|=uaks zlcMWII^j2iGrFH(k7q&)?FU;)u>)&wA6=5jD955Q=V|KhSi(sRB#rSS2E8-Fn)z4= z+vN1n^bueR#H42PS)IJ_LNGI1j2HZu2U`#H;S+-Gij;10cgtMMi{Vz^5tkbP;KL&= z=6WWtwbVnRqN5+J7Olu@h>i9BxC_)gD((TbpC+j>rlU%b0-$YTC;_;BF5Q@K`9F{w zb4ZRqg0;#P1J&Yg7}FnC=@u?G!8F`y!vdhvl}H-a~(TXLEE= znlL!{LJj*fka@+l7XKGUu*!pJ5-T;~u2WDu(DsAx2PnY9u2xnRc&`8_-l0530Ugzk zGWT6cAgN67$h6h5>|P3Dls2wVv-clJWNps9QtP@NT%Ob5ovp$d?=YT?&=}NH48j0L zLFPMK5sQD>D9~$!{rCltcAOY#I{=GP`|{z&ANns?RMHZvOd{gfigN?3@v(Akeo*N} zdFFa*?Mo4N!uKa@@HaPIf;Cr_QkJ3JF{$2?) z99m;I(2~BvTHSQ(qsP6&jZ4>x58^e_PD`sym-^q&q1jr=ADv7R60%2HcSrK?B4m{< zsRL+10Z#ar0XgDN7r@jUAX!%H=!$t@aAq#BF*EzB%wEI9~&dZCfNfQ?ZZ`&qpac+$oB5EzD37ub+Th{(F%e%Mc zIbEW7g`bs|>BojCKVWexU`LG`dF?mvM0vk&lLsUkRp5RKw`Kw{cpAFLQvhl^s!goi zIiZXeX!W`Ur+x%}#+LWf!P6nLZ8(~{d7jt+3(0;P2=cgfOOcn3GQc9#oCFu#q+Z)i zYB{X$DCkKULs#n8YGX4nn@(j#x31aTrO7sD3G1Bo4YlVhFDUu=N?i@^J#`lir=kWh z)Sj0N|GCX8Z%}^FMI%8V0(WF7?&s=;SjShaLjx|hOhTD6Vu-Up(mNiKV_Gr;JCaoB zB^C0}XEoG3TCZ$ep9Hav+iK%&q`G|xi&FUV7ycktlrflN|ytFYmh zgnPWVtB7sdgQk48WkNldRtgmw+I&5U;Hc2{iK($mhSodMt4e z<)r%(kL@!d+@=B*X-0rRHwIr!tOUper_x}BtWxEmmmH0WfdVTvV>-}e;xaqo3vBoN zub*s2h%Ii6;vWgj?AqRmdkz{d&pk^o>r0v?okV=-GY)?K_wC$MenGzMljn2(2dO8! A)c^nh literal 0 HcmV?d00001 diff --git a/docs/templates/header.h b/docs/templates/header.h new file mode 100755 index 0000000..82dc3df --- /dev/null +++ b/docs/templates/header.h @@ -0,0 +1,299 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: header.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| STRUCTS: || +|| -------- || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| - Patrick Vogler B87D120 V - header file created || +|| - Patrick Vogler B880CA2 V - header file patched || +|| - Patrick Vogler B87E7E4 V - header file updated || +|| - Patrick Vogler B87F684 V - header file new version || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef HEADER_H +#define HEADER_H + + /************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************************/ + + /************************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + ! Macros: ! + ! ------- ! + ! Macro Description ! + ! ----- ----------- ! + ! ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! - Patrick Vogler B87D120 V - Macros created ! + ! - Patrick Vogler B880CA2 V - Macros patched ! + ! - Patrick Vogler B87E7E4 V - Macros updated ! + ! - Patrick Vogler B87F684 V - Macros new version ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + + /************************************************************************************************************\ + || ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || + || | | | |\ | [__ | |__| |\ | | [__ || + || |___ |__| | \| ___] | | | | \| | ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + ! CONSTANTS: ! + ! ----------- ! + ! Constant Description ! + ! -------- ----------- ! + ! ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! - Patrick Vogler B87D120 V - Constants created ! + ! - Patrick Vogler B880CA2 V - Constants patched ! + ! - Patrick Vogler B87E7E4 V - Constants updated ! + ! - Patrick Vogler B87F684 V - Constants new version ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + /************************************************************************************************************\ + || ____ _ _ ___ ____ ____ _ _ ____ _ _ _ ____ ____ _ ____ ___ _ ____ ____ || + || |___ \/ | |___ |__/ |\ | |__| | | | |__| |__/ | |__| |__] | |___ [__ || + || |___ _/\_ | |___ | \ | \| | | |___ \/ | | | \ | | | |__] |___ |___ ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + ! VARIABLES: ! + ! ----------- ! + ! VARIABLE Description ! + ! -------- ----------- ! + ! ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! - Patrick Vogler B87D120 V - Variables created ! + ! - Patrick Vogler B880CA2 V - Variables patched ! + ! - Patrick Vogler B87E7E4 V - Variables updated ! + ! - Patrick Vogler B87F684 V - Variables new version ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + /************************************************************************************************************\ + || ____ _ _ ___ ____ ____ _ _ ____ _ ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || + || |___ \/ | |___ |__/ |\ | |__| | | | | |\ | [__ | |__| |\ | | [__ || + || |___ _/\_ | |___ | \ | \| | | |___ |___ |__| | \| ___] | | | | \| | ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + ! CONSTANTS: ! + ! ----------- ! + ! Constant Description ! + ! -------- ----------- ! + ! ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! - Patrick Vogler B87D120 V - Constants created ! + ! - Patrick Vogler B880CA2 V - Constants patched ! + ! - Patrick Vogler B87E7E4 V - Constants updated ! + ! - Patrick Vogler B87F684 V - Constants new version ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + /************************************************************************************************************\ + || ___ _ _ ___ ____ ____ || + || | \_/ |__] |___ [__ || + || | | | |___ ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: Template ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! - Patrick Vogler B87D120 V - Struct created ! + ! - Patrick Vogler B880CA2 V - Struct patched ! + ! - Patrick Vogler B87E7E4 V - Struct updated ! + ! - Patrick Vogler B87F684 V - Struct new version ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + + /*----------------------------------------------------------------------------------------------------------*\ + ! ENUM NAME: Template ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! - Patrick Vogler B87D120 V - Enum created ! + ! - Patrick Vogler B880CA2 V - Enum patched ! + ! - Patrick Vogler B87E7E4 V - Enum updated ! + ! - Patrick Vogler B87F684 V - Enum new version ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + + /*----------------------------------------------------------------------------------------------------------*\ + ! UNION NAME: Template ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! - Patrick Vogler B87D120 V - Union created ! + ! - Patrick Vogler B880CA2 V - Union patched ! + ! - Patrick Vogler B87E7E4 V - Union updated ! + ! - Patrick Vogler B87F684 V - Union new version ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + + /************************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************************/ + + /*----------------------------------------------------------------------------------------------------------*\ + ! TYPE NAME: Template ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ +#endif \ No newline at end of file diff --git a/docs/templates/source.c b/docs/templates/source.c new file mode 100755 index 0000000..626cde2 --- /dev/null +++ b/docs/templates/source.c @@ -0,0 +1,179 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| FILE NAME: source.c || +|| || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| FILE REFERENCES: || +|| ---------------- || +|| || +|| Name I/O Description || +|| ---- --- ----------- || +|| none - - || +|| || +|| || +|| PRIVATE FUNCTIONS: || +|| ------------------ || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| - Patrick Vogler B87D120 V - source file created || +|| - Patrick Vogler B880CA2 V - source file patched || +|| - Patrick Vogler B87E7E4 V - source file updated || +|| - Patrick Vogler B87F684 V - source file new version || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ + +/************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\************************************************************************************************************/ +/************************************************************************************************************\ +|| ____ _ _ ___ ____ ____ _ _ ____ _ _ _ ____ ____ _ ____ ___ _ ____ ____ || +|| |___ \/ | |___ |__/ |\ | |__| | | | |__| |__/ | |__| |__] | |___ [__ || +|| |___ _/\_ | |___ | \ | \| | | |___ \/ | | | \ | | | |__] |___ |___ ___] || +|| || +\************************************************************************************************************/ +/************************************************************************************************************\ +|| ____ _ _ ___ ____ ____ _ _ ____ _ ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || +|| |___ \/ | |___ |__/ |\ | |__| | | | | |\ | [__ | |__| |\ | | [__ || +|| |___ _/\_ | |___ | \ | \| | | |___ |___ |__| | \| ___] | | | | \| | ___] || +|| || +\************************************************************************************************************/ + +/************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *template(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V - function created ! +! - Patrick Vogler B880CA2 V - function patched ! +! - Patrick Vogler B87E7E4 V - function updated ! +! - Patrick Vogler B87F684 V - function new version ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ + +/************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V - function created ! +! - Patrick Vogler B880CA2 V - function patched ! +! - Patrick Vogler B87E7E4 V - function updated ! +! - Patrick Vogler B87F684 V - function new version ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +/*-----------------------*\ +! DEFINE INT VARIABLES: ! +\*-----------------------*/ +/*-----------------------*\ +! DEFINE FLOAT VARIABLES: ! +\*-----------------------*/ +/*-----------------------*\ +! DEFINE CHAR VARIABLES: ! +\*-----------------------*/ +/*-----------------------*\ +! DEFINE STRUCTS: ! +\*-----------------------*/ +/*--------------------------------------------------------*\ +! COMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENT ! +\*--------------------------------------------------------*/ \ No newline at end of file diff --git a/include/interfaces/reader/eas3.h b/include/interfaces/reader/eas3.h new file mode 100644 index 0000000..702adde --- /dev/null +++ b/include/interfaces/reader/eas3.h @@ -0,0 +1,336 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: header.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This file defines simple read and write functions used to access conforming eas3 datasets. || +|| || +|| STRUCTS: || +|| -------- || +|| - eas3_std_params || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| - read_eas3 || +|| - write_eas3 || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| - Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef EAS3_H +#define EAS3_H + + /************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************************/ + #include + #include + #include + + /************************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros are used to identify the spatial and temporal dimensions. ! + ! ! + ! MACROS: ! + ! ------- ! + ! Name Description ! + ! ---- ----------- ! + ! DIM_X, DIM_Y, DIM_Z - Spatial Dimensions ! + ! ! + ! DIM_TS - Temporal Dimension ! + ! ! + ! DIM_ALL - All Dimensions ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description ! + ! ---- ------ --------- ------- ----------- ! + ! 04.12.2017 Patrick Vogler B87D120 V 0.1.0 macros created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + #define DIM_X 1 + #define DIM_Y 2 + #define DIM_Z 4 + #define DIM_TS 8 + #define DIM_ALL 15 + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros are used to instruct the read_eas3_header function. ! + ! ! + ! Macros: ! + ! ------- ! + ! Macro Description ! + ! ----- ----------- ! + ! EAS3_NO_ATTR 1 - Specifies that no attributes are present in the bit- ! + ! stream. ! + ! ! + ! EAS3_ALL_ATTR 2 - Specifies that all attributes are present in the bit- ! + ! bitstream. ! + ! ! + ! ATTRLEN 10 - Defines the number of bytes used to define an attrib- ! + ! ute. ! + ! ! + ! UDEFLEN 20 - Defines the number of bytes used to define a user de- ! + ! fined data. ! + ! ! + ! EAS3_NO_G 1 - Specifies that no geometry data is present in the bit- ! + ! stream. ! + ! ! + ! EAS3_X0DX_G 2 - Specifies that a start value and step size are present ! + ! in the bitstream. ! + ! ! + ! EAS3_UDEF_G 3 - Specifies that ng = number of coordinate data is pres- ! + ! ent in the bitstream. ! + ! ! + ! EAS3_ALL_G 4 - Specifies that an element for every appropriate di- ! + ! mension is present in the bitstream. ! + ! ! + ! EAS3_FULL_G 5 - Specifies that an element for every dimension is pres- ! + ! ent in the bitstream. ! + ! ! + ! EAS3_NO_UDEF 1 - Specifies that no user defined data is present in the ! + ! bitstream. ! + ! ! + ! EAS3_ALL_UDEF 2 - Specifies that all user defined fields are present in ! + ! the bitstream. ! + ! ! + ! EAS3_INT_UDEF 3 - Specifies that an user defined integer field is pres- ! + ! ent in the bitstream. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 Macros created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define EAS3_NO_ATTR 0x100000000000000 + #define EAS3_ALL_ATTR 0x200000000000000 + + #define EAS2_TYPE 0x100000000000000 + #define EAS3_TYPE 0x200000000000000 + + #define ATTRLEN 10 + #define UDEFLEN 20 + + #define EAS3_NO_G 0x100000000000000 + #define EAS3_X0DX_G 0x200000000000000 + #define EAS3_UDEF_G 0x300000000000000 + #define EAS3_ALL_G 0x400000000000000 + #define EAS3_FULL_G 0x500000000000000 + + #define EAS3_NO_UDEF 0x100000000000000 + #define EAS3_ALL_UDEF 0x200000000000000 + #define EAS3_INT_UDEF 0x300000000000000 + + #define AUX_SIZE 0x8000 + + /************************************************************************************************************\ + || ___ _ _ ___ ____ ____ || + || | \_/ |__] |___ [__ || + || | | | |___ ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: eas3_header ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure is used to store the eas3 header information. For a more thorough discussion ! + ! of the eas3 datatype see: ! + ! ! + ! https://wiki.iag.uni-stuttgart.de/eas3wiki/index.php/EAS3_File_Format/de ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! file_type unsigned int(64 bit) - Defines an identifier for the EAS type. ! + ! ! + ! accuracy unsigned int(64 bit) - Defines the accuracy of an eas3 file. ! + ! ! + ! nzs unsigned int(64 bit) - Variable defining the temporal size of ! + ! the uncompressed dataset. ! + ! ! + ! npar unsigned int(64 bit) - Defines the number of parameters in the ! + ! eas3 dataset. ! + ! ! + ! ndim1, -2, -3 unsigned int(64 bit) - Variables defining the spatial size of ! + ! the eas3 dataset. ! + ! ! + ! attribute_mode; unsigned int(64 bit) - Defines an identifier used to signal ! + ! the attribute mode of the eas3 file. ! + ! ! + ! gmode_time unsigned int(64 bit) - Defines the geometry mode for the temp- ! + ! oral dimension. ! + ! ! + ! gmode_param unsigned int(64 bit) - Defines the geometry mode for the para- ! + ! meters. ! + ! ! + ! gmode_dim1 unsigned int(64 bit) - Defines the geometry mode for the first ! + ! spatial dimension. ! + ! ! + ! gmode_dim2 unsigned int(64 bit) - Defines the geometry mode for the sec- ! + ! ond spatial dimension. ! + ! ! + ! gmode_dim3 unsigned int(64 bit) - Defines the geometry mode for the third ! + ! spatial dimension. ! + ! ! + ! size_time unsigned int(64 bit) - Defines the geometry array size for the ! + ! temporal dimension. ! + ! ! + ! size_parameter unsigned int(64 bit) - Defines the geometry array size for the ! + ! parameters. ! + ! ! + ! size_dim1 unsigned int(64 bit) - Defines the geometry array size for the ! + ! first spatial dimension. ! + ! ! + ! size_dim2 unsigned int(64 bit) - Defines the geometry array size for the ! + ! second spatial dimension. ! + ! ! + ! size_dim3 unsigned int(64 bit) - Defines the geometry array size for the ! + ! third spatial dimension. ! + ! ! + ! udef_param unsigned int(64 bit) - Defines a marker used to signal which ! + ! user defined parameters are present in ! + ! the eas3 file. ! + ! ! + ! udef_char_size unsigned int(64 bit) - Defines the size for the user defined ! + ! char array. ! + ! ! + ! udef_int_size unsigned int(64 bit) - Defines the size for the user defined ! + ! int array. ! + ! ! + ! udef_real_size unsigned int(64 bit) - Defines the size for the user defined ! + ! real array. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64_t file_type; + uint64_t accuracy; + uint64_t nzs; + uint64_t npar; + uint64_t ndim1; + uint64_t ndim2; + uint64_t ndim3; + uint64_t attribute_mode; + uint64_t gmode_time; + uint64_t gmode_param; + uint64_t gmode_dim1; + uint64_t gmode_dim2; + uint64_t gmode_dim3; + uint64_t size_time; + uint64_t size_parameter; + uint64_t size_dim1; + uint64_t size_dim2; + uint64_t size_dim3; + uint64_t udef_param; + uint64_t udef_char_size; + uint64_t udef_int_size; + uint64_t udef_real_size; + } eas3_std_params; + + /************************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: bwc_data* read_eas3(const char* const filename) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function opens an eas3 file and checks it for its validity. Once the specified file ! + ! has been verified, its header and flow field data is read and stored in the bwc_data ! + ! structure. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + bwc_data* + read_eas3(char *const filename); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: uchar write_eas3(bwc_data *const file, char *const filename) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function creates a valid eas3 file from the information stored in the bwc_data ! + ! structure. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + write_eas3(bwc_data *const file, char *const filename); +#endif \ No newline at end of file diff --git a/include/library/private/bitstream.h b/include/library/private/bitstream.h new file mode 100755 index 0000000..001bca4 --- /dev/null +++ b/include/library/private/bitstream.h @@ -0,0 +1,224 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: bwc_bitstream.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This file describes a set of functions that can be used to create, manipulate and terminate || +|| a bitstream. These functions facilitate the creation or reading of a compressed bwc code- || +|| stream and can emit/extract information on a per bit, symbol (64-bit) or string basis. || +|| || +|| || +|| STRUCTS: || +|| -------- || +|| - || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| - bwc_init_stream || +|| - bwc_emit_chunck || +|| - bwc_emit_symbol || +|| - bwc_emit_bit || +|| - bwc_get_chunck || +|| - bwc_get_symbol || +|| - bwc_get_bit || +|| - bwc_terminate_stream || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 28.05.2018 Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef BITSTREAM_H +#define BITSTREAM_H + + /************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************************/ + #include "types.h" + + /************************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: uint32 bytes_used(bwc_stream *const stream) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function is used to evaluate the number of bytes that have already been ! + ! written to the allocated bitstream memory block. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uint64 + bytes_used(bwc_stream *const stream); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: bwc_stream* bwc_init_stream(uchar* memory, uint32 size, char instr) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function is used to initialize a bwc bitstream. For encoding, a null pointer ! + ! is passed as a memory handle and the function will allocate a memory block with the ! + ! specified stream size. For decoding, a valid memory handle, passed by the function ! + ! caller, will be stored in the bwc_stream structure. The byte buffer counter t, ! + ! stream size Lmax and size increment are initialized with their appropriate values. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + bwc_stream* + bwc_init_stream(uchar* memory, uint32 size, char instr); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_emit_chunck(bwc_stream *const stream, const uchar* chunck, const uint64 size); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_emit_symbol(bwc_stream *const stream, const uint64 symbol, const uint8 size); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_emit_bit(bwc_stream *const stream, const uint64 bit); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + flush_stream(bwc_stream *const stream); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar* + bwc_get_chunck(bwc_stream *const stream, const uint64 length); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uint64 + bwc_get_symbol(bwc_stream *const stream, const uint8 length); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + bwc_get_bit(bwc_stream *const stream); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + bwc_terminate_stream(bwc_stream *stream, bwc_packed_stream *const packed_stream); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void release_packed_stream(bwc_packed_stream *stream) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function is used to release all the information stored in a packed bitstream ! + ! and reset the parameters for another (de)compression run. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + release_packed_stream(bwc_packed_stream *stream); +#endif \ No newline at end of file diff --git a/include/library/private/codestream.h b/include/library/private/codestream.h new file mode 100755 index 0000000..0458d2c --- /dev/null +++ b/include/library/private/codestream.h @@ -0,0 +1,191 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: codestream.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| STRUCTS: || +|| -------- || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 28.05.2018 Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef CODESTREAM_H +#define CODESTREAM_H + + /************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************************/ + #include "types.h" + + /************************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! These macros define stream manipulation operations to rewind, foward and get access ! + ! to the current memory position of a bwc_stream. ! + ! ! + ! Macros: ! + ! ------- ! + ! Macro Description ! + ! ----- ----------- ! + ! rewind_stream - Rewinds a stream by a user specified amount (delta) ! + ! of bits. ! + ! ! + ! foward_stream - Fowards a stream by a user specified amount (delta) ! + ! of bits. ! + ! ! + ! get_access - Get an access pointer to the current memory position ! + ! of a bwc_stream. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 07.08.2019 Patrick Vogler B87D120 V 0.1.0 Macros created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define rewind_stream(stream, delta) \ + { \ + stream->L -= delta; \ + } + + #define forward_stream(stream, delta) \ + { \ + stream->L += delta; \ + } + + #define get_access(stream) (uchar*)stream->memory + stream->L + + /************************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + assemble_main_header(bwc_field *const field); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + bwc_field* + bwc_parse_main_header(bwc_data *const data,bwc_stream *const stream); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + codestream_write_aux(bwc_packed_stream *const header, bwc_packed_stream *const aux); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + codestream_write_com(bwc_packed_stream *const header, bwc_packed_stream *const com); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: bwc_packed_stream* assemble_codestream(bwc_field *const field) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + bwc_packed_stream* + assemble_codestream(bwc_field *const field); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: bwc_field* parse_codestream(bwc_data *const data) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + bwc_field* + parse_codestream(bwc_data *const data, uint8 const layer); +#endif \ No newline at end of file diff --git a/include/library/private/constants.h b/include/library/private/constants.h new file mode 100755 index 0000000..c33f78f --- /dev/null +++ b/include/library/private/constants.h @@ -0,0 +1,328 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: constants.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| STRUCTS: || +|| -------- || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 16.10.2017 Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef CONSTANTS_H +#define CONSTANTS_H + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These constants are used to identify the spatial and temporal dimensions. ! + ! ! + ! Constants: ! + ! ----------- ! + ! Constant Description ! + ! -------- ----------- ! + ! DIM_X 1st Spatial Dimension ! + ! DIM_Y 2nd Spatial Dimension ! + ! DIM_Z 3rd Spatial Dimension ! + ! DIM_TS Temporal Dimension ! + ! DIM_ALL All Dimensions ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 04.12.2017 Patrick Vogler B87D120 V 0.1.0 Constants created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define DIM_X 1 + #define DIM_Y 2 + #define DIM_Z 4 + #define DIM_TS 8 + #define DIM_ALL 15 + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These constants describe the maximum allowable wavelet decompositions for the spatial and ! + ! temporal dimensions and the maximum allowable subbands. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 01.12.2017 Patrick Vogler B87D120 V 0.1.0 Constants created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define MAXIMUM_NUMBER_OF_SPATIAL_DECOMP 64 + #define MAXIMUM_NUMBER_OF_TEMPORAL_DECOMP 32 + #define MAXIMUM_NUMBER_OF_SUBBANDS (1+(15*(64-32))) + (1+(7*32)) + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These Constants describe the codestream markers used to create the embedded codestream. ! + ! ! + ! CONSTANTS: ! + ! ----------- ! + ! Constant Description ! + ! -------- ----------- ! + ! SOC - Start of code-stream ! + ! SGI - Global data-set information ! + ! SGC - Global control parameters ! + ! SAX - Auxiliary data-set information ! + ! TLM - Packet lengths: main header ! + ! PLM - Packet lengths: tile-part ! + ! PPM - Quantization default ! + ! COM - Comment ! + ! EOH - End of header ! + ! PLT - Packed packet headers: main header ! + ! PPT - Packed packet headers: tile-part ! + ! SOT - Start of tile ! + ! SOP - Start of packet ! + ! EPH - End of packet header ! + ! SOD - Start of data ! + ! EOC - End of code-stream ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 01.12.2017 Patrick Vogler B87D120 V 0.1.0 Constants created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define SOC 0xFF50 + #define SGI 0xFF51 + #define SGC 0xFF52 + #define SAX 0xFF53 + #define TLM 0xFF54 + #define PLM 0xFF55 + #define PPM 0xFF56 + #define COM 0xFF57 + #define EOH 0xFF58 + #define PLT 0xFF60 + #define PPT 0xFF61 + #define SOT 0xFF90 + #define SOP 0xFF91 + #define EPH 0xFF92 + #define SOD 0xFF93 + #define EOC 0xFFFF + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These Constants are used for codestream parsing. ! + ! ! + ! CONSTANTS: ! + ! ----------- ! + ! Constant Description ! + ! -------- ----------- ! + ! CODESTREAM_OK No errors detectet in Codestream ! + ! CODESTREAM_ERROR Error detectet in Codestream ! + ! CODESTREAM_SGI_READ Global data-set information read ! + ! CODESTREAM_SGC_READ Global control parameters read ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 01.08.2019 Patrick Vogler B87D120 V 0.1.0 Constants created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define CODESTREAM_OK 0x00 + #define CODESTREAM_ERROR 0x80 + #define CODESTREAM_SGI_READ 0x01 + #define CODESTREAM_SGC_READ 0x02 + #define CODESTREAM_SAX_READ 0x04 + #define CODESTREAM_COM_READ 0x08 + + /*----------------------------------------------------------------------------------------------------------*\ + ! ENUM NAME: bwc_dwt_filter ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These constants describe the wavelet filter used during the transform stage. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Constant Description ! + ! -------- ----------- ! + ! bwc_dwt_9_7 - Cohen Daubechies Feauveau 9/7 Wavelet ! + ! bwc_dwt_5_3 - LeGall 5/3 Wavelet ! + ! bwc_dwt_haar - Haar Wavelet ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 07.12.2017 Patrick Vogler B87D120 V 0.1.0 Enum created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef enum{ + bwc_dwt_9_7, + bwc_dwt_5_3, + bwc_dwt_haar + } bwc_dwt_filter; + + /*----------------------------------------------------------------------------------------------------------*\ + ! ENUM NAME: bwc_prog_ord ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These constants describe the progression order used to pack the codestream. ! + ! The organisation of the codesstream is carried out according to the following 5 cases. ! + ! ! + ! LRCP: RLCP: ! + ! ----- for each Quality Layer: ----- for each Resolution: ! + ! for each Resolution: for each Quality Layer: ! + ! for each Parameter: for each Parameter: ! + ! for each Precinct: for each Precinct: ! + ! include Packet include Packet ! + ! ! + ! RPCL: PCRL: ! + ! ----- for each Resolution: ----- for each Precinct: ! + ! for each Precinct: for each Parameter: ! + ! for each Parameter: for each Resolution: ! + ! for each Quality Layer: for each Quality Layer: ! + ! include Packet include Packet ! + ! ! + ! CPRL: ! + ! ----- for each Quality Layer: ! + ! for each Resolution: ! + ! for each Parameter: ! + ! for each Precinct: ! + ! include Packet ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Constant Description ! + ! -------- ----------- ! + ! bwc_prog_LRCP - LRCP progression order ! + ! bwc_prog_RLCP - RLCP progression order ! + ! bwc_prog_RPCL - RPCL progression order ! + ! bwc_prog_PCRL - PCRL progression order ! + ! bwc_prog_CPRL - CPRL progression order ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 07.12.2017 Patrick Vogler B87D120 V 0.1.0 Enum created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef enum{ + bwc_prog_LRCP, + bwc_prog_RLCP, + bwc_prog_RPCL, + bwc_prog_PCRL, + bwc_prog_CPRL + } bwc_prog_ord; + + /*----------------------------------------------------------------------------------------------------------*\ + ! ENUM NAME: bwc_quant_st ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Constant Description ! + ! -------- ----------- ! + ! - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 07.12.2017 Patrick Vogler B87D120 V 0.1.0 Enum created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef enum{ + bwc_qt_none, + bwc_qt_derived, + } bwc_quant_st; + + /*----------------------------------------------------------------------------------------------------------*\ + ! ENUM NAME: bwc_tile_instr ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Constant Description ! + ! -------- ----------- ! + ! - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 17.04.2019 Patrick Vogler B87D120 V 0.1.0 Enum created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef enum{ + bwc_tile_sizeof, + bwc_tile_numbof, + } bwc_tile_instr; +#endif \ No newline at end of file diff --git a/include/library/private/dwt.h b/include/library/private/dwt.h new file mode 100755 index 0000000..8265a03 --- /dev/null +++ b/include/library/private/dwt.h @@ -0,0 +1,328 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: dwt.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| STRUCTS: || +|| -------- || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 21.03.2018 Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef DWT_H +#define DWT_H + /************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************************/ + #include "types.h" + + /************************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This macro defines the maximum decomposition level up to which the wavelet filer energy gain ! + ! is calculated. Beyond the maximum decomposition level the energy gain will only be ! + ! approximated. ! + ! ! + ! Macros: ! + ! ------- ! + ! Macro Description ! + ! ----- ----------- ! + ! MAX_DECOMPOSITION_LEVELS - Maximum number of wavelet layers for which the energy ! + ! gain is calculated. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 20.03.2018 Patrick Vogler B87D120 V 0.1.0 Macros created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define MAX_DECOMPOSITION_LEVELS 4 + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros define the irrational coefficients for the high and low pass synthesis filters ! + ! associated with the (9-7) Cohen-Daubechies-Feauveau-Wavelet as well as the coefficients for ! + ! its coressponding lifting scheme. ! + ! ! + ! Macros: ! + ! ------- ! + ! Macro Description ! + ! ----- ----------- ! + ! DWT_9X7_H0 ! + ! DWT_9X7_H1 ! + ! DWT_9X7_H2 - Coefficients for the (9-7) ! + ! DWT_9X7_H3 low pass synthesis filter. ! + ! ! + ! DWT_9X7_G0 ! + ! DWT_9X7_G1 ! + ! DWT_9X7_G2 ! + ! DWT_9X7_G3 - Coefficients for the (9-7) ! + ! DWT_9X7_G4 high pass synthesis filter. ! + ! ! + ! ALPHA ! + ! BETA ! + ! GAMMA ! + ! DELTA ! + ! KAPPA_H - Coefficients for the (9-7) ! + ! KAPPA_L lifting scheme. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 20.03.2018 Patrick Vogler B87D120 V 0.1.0 Macros created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define DWT_9X7_H0 1.115087052457000f + #define DWT_9X7_H1 0.591271763114250f + #define DWT_9X7_H2 -0.057543526228500f + #define DWT_9X7_H3 -0.091271763114250f + + #define DWT_9X7_G0 1.205898036472721f + #define DWT_9X7_G1 -0.533728236885750f + #define DWT_9X7_G2 -0.156446533057980f + #define DWT_9X7_G3 0.033728236885750f + #define DWT_9X7_G4 0.053497514821620f + + #define ALPHA -1.586134342059924f + #define BETA -0.052980118572961f + #define GAMMA 0.882911075530934f + #define DELTA 0.360523644801462f + #define KAPPA_H 1.230174104914001f + #define KAPPA_L 0.812893066115961f + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros define the irrational coefficients for the high and low pass synthesis filters ! + ! associated with the (5-3) LeGall-Wavelet. ! + ! ! + ! Macros: ! + ! ------- ! + ! Macro Description ! + ! ----- ----------- ! + ! DWT_5X3_H0 - Coefficients for the (9-7) ! + ! DWT_5X3_H1 low pass synthesis filter. ! + ! ! + ! DWT_5X3_G0 ! + ! DWT_5X3_G1 - Coefficients for the (9-7) ! + ! DWT_5X3_G2 high pass synthesis filter. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 20.03.2018 Patrick Vogler B87D120 V 0.1.0 Macros created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define DWT_5X3_H0 1.0f + #define DWT_5X3_H1 0.5f + + #define DWT_5X3_G0 0.75f + #define DWT_5X3_G1 -0.25f + #define DWT_5X3_G2 -0.125f + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros define the irrational coefficients for the high and low pass synthesis filters ! + ! associated with the Haar-Wavelet. ! + ! ! + ! Macros: ! + ! ------- ! + ! Macro Description ! + ! ----- ----------- ! + ! DWT_HAAR_G0 - Coefficients for the Haar ! + ! DWT_HAAR_G1 low pass synthesis filter. ! + ! ! + ! DWT_HAAR_H1 - Coefficients for the Haar ! + ! DWT_HAAR_H2 high pass synthesis filter. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 20.03.2018 Patrick Vogler B87D120 V 0.1.0 Macros created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define DWT_HAAR_H0 1 + #define DWT_HAAR_H1 1 + + #define DWT_HAAR_G0 0.5 + #define DWT_HAAR_G1 -0.5 + + /************************************************************************************************************\ + || ____ _ _ ___ ____ ____ _ _ ____ _ _ _ ____ ____ _ ____ ___ _ ____ ____ || + || |___ \/ | |___ |__/ |\ | |__| | | | |__| |__/ | |__| |__] | |___ [__ || + || |___ _/\_ | |___ | \ | \| | | |___ \/ | | | \ | | | |__] |___ |___ ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This array defines a lookup table used to store the energy gain factors for the one dimen- ! + ! sional, dyadic tree structured CDF-(9/7), LeGall-(5/3) and Haar wavelet transform. Each LUT ! + ! contains energy gain factors for the 6 low-pass and 6 high-pass decomposition including level ! + ! zero. ! + ! ! + ! VARIABLES: ! + ! ----------- ! + ! Variable Description ! + ! -------- ----------- ! + ! DWT_ENERGY_GAIN_LUT - Lookup-table for the CDF-(9/7), LG-(5/3) and Haar ! + ! dwt energy gain factor. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 21.03.2018 Patrick Vogler B87D120 V 0.1.0 Variables created ! + \*----------------------------------------------------------------------------------------------------------*/ + extern double DWT_ENERGY_GAIN_LUT[3][2 * MAX_DECOMPOSITION_LEVELS + 2]; + + /************************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: uchar initialize_gain_lut() ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function calculates the energy gain factor Gb for the one dimensional, dyadic tree ! + ! structured CDF-(9/7), LeGall-(5/3) and Haar wavelet transform with 5 levels. The energy ! + ! gain factors are calculated according to equation (4.39) from JPEG2000 by David S. Taubman ! + ! and Michael W. Marcellin (p. 193): ! + ! ! + ! s_L1[n] = g0[n], s_H1[n] = h0[n], ! + ! s_Ld[n] = ∑(s_Ld-1[k]*g0[n-2k], k), s_Hd[n] = ∑(s_Hd-1[k]*g0[n-2k], k). ! + ! ! + ! The energy gain factors are stored in their corresponding lookup tables and used to calcu- ! + ! late the energy gain for the multi dimensional wavelet transforms according to equation ! + ! (4.40) from JPEG2000 by David S. Taubman and Michael W. Marcellin (p.193): ! + ! ! + ! s_LLD[n1,n2] = s_LD[n1] * s_LD[n2] => G_LLD = G_LD * G_LD ! + ! s_HLD[n1,n2] = s_LD[n1] * s_HD[n2] => G_HLD = G_LD * G_HD ! + ! s_LHD[n1,n2] = s_HD[n1] * s_LD[n2] => G_LHD = G_HD * G_LD ! + ! s_HHD[n1,n2] = s_HD[n1] * s_HD[n2] => G_HHD = G_HD * G_HD ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + initialize_gain_lut(); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: bwc_float get_dwt_energy_gain(bwc_field *field, uchar highband_flag, uint level) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function evaluates the energy gain factor according to the the specified decomposition ! + ! level. For decomposition levels larger than MAX_DECOMPOSITION_LEVELS the filter gain for ! + ! the extra levels is approximated by multiplying the energy gain factor by 2. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + bwc_float + get_dwt_energy_gain(bwc_field *field, uchar highband_flag, uint16 level); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: uchar forward_discrete_wavelet_transform(bwc_field *const field, ! + ! -------------- bwc_parameter *const parameter) ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function performs the forward discrete wavelet transform on the current tile param- ! + ! eter. After loading the flow field samples for a row, column or spatial/temporal slice ! + ! into a working buffer, a boundary extension operation is performed to ensure an approp. ! + ! sample base. The working buffer is then transform using the wavelet kernel selected for ! + ! the spatial or temporal dimension, sorted into high- and low-frequency samples and flushed ! + ! back into the tile parameter memory block. This operation is performed for every row, ! + ! column and spatial/temporal slice for ndecomp number of decomposition levels. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + forward_discrete_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: uchar inverse_discrete_wavelet_transform(bwc_field *const field, ! + ! -------------- bwc_parameter *const parameter) ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function performs the inverse discrete wavelet transform on the current tile param- ! + ! eter. After loading the interweaved wavelet coefficients for a row, column or spatial/ ! + ! temporal slice into a working buffer, a boundary extension operation is performed to ! + ! ensure an appropriate sample base. The working buffer is then transform using the wave- ! + ! let kernel selected for the spatial or temporal dimension and flushed back into the tile ! + ! parameter memory block. This operation is performed for every row, column and spatial/ ! + ! temporal slice for ndecomp number of decomposition levels. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + inverse_discrete_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter); +#endif \ No newline at end of file diff --git a/include/library/private/libbwc.h b/include/library/private/libbwc.h new file mode 100755 index 0000000..fcf36a1 --- /dev/null +++ b/include/library/private/libbwc.h @@ -0,0 +1,394 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| Version 0.1.1 || +|| || +|| File: bwc.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This header defines DESCRIPTION NEEDED. || +|| || +|| STRUCTS: || +|| -------- || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| - bwc_kill_compression || +|| - bwc_add_param || +|| - bwc_set_quantization_style || +|| - bwc_set_progression || +|| - bwc_set_kernels || +|| - bwc_set_levels || +|| - bwc_set_codeblocks || +|| - bwc_set_qm || +|| - bwc_set_tiles || +|| - bwc_initialize_compression || +|| - bwc_create_compression || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| - Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef BWC_H +#define BWC_H + /************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************************/ + #include "bitstream.h" + #include "codestream.h" + #include "constants.h" + #include "macros.h" + #include "mq_types.h" + #include "types.h" + + /************************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: bwc_field *bwc_initialize_data(...) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function initializes the bwc_data structure with all necessary parameters. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + bwc_data* + bwc_initialize_data(double* field, uint64 const nX, uint64 const nY, uint64 const nZ, uint16 const nTS, uint8 const nPar, char *file_extension); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_add_param(bwc_data* data, char *name, uint16 sample, uchar dim, uint8 precision) ! + ! -------------- ! + ! ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function initializes and adds new parameters to the parameter linked list. The linked ! + ! list stores the parameter name, its precision, sampling factor and the dimension for which ! + ! the sampling is active. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_add_param(bwc_data* data, char *name, uint16 sample, uchar dim, uint8 precision); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: bwc_field *bwc_initialize_data(...) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function is used to copy the numerical dataset stored in the bwc_data ! + ! structure to a user supplied memory block. A size argument is necessary ! + ! to verify that the memory block has the correct size. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_get_data(bwc_data* data, uchar* buffer, uint64 size); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_free_data(bwc_data* file) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function deallocates the data structure used to store an numerical dataset/compressed ! + ! and can be called if an error occurs or once the data is no longer needed is to be closed. ! + ! The deallocation will be carried out down to the structure levels that have been allocated. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_free_data(bwc_data* data); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: uchar create_field(bwc_field *const field) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function creates the field structure used to (de)compress a floating point array de- ! + ! fined by the bwc_initialize function. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + create_field(bwc_field *const field); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void kill_compression(bwc_field *const field) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function deallocates the compression field structure used to define and control the ! + ! bwc codec and can be called if an error occurs during the (de-)compression stage or once ! + ! the codec has finished. The deallocation will be carried out down to the structure levels ! + ! that have been allocated. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_kill_compression(bwc_field *const field); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: bwc_field *bwc_initialize_field(bwc_data *const data) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function initializes the bwc_field structure with all necessary standard parameters ! + ! to (de)compress a floating point array with nX * nY * nZ grid points, nTS timesteps and ! + ! nPar parameters. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + bwc_field* + bwc_initialize_field(bwc_data *const data); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_set_error_resilience(bwc_field *const field) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function sets the error resilience marker in the bwc_field structure if an error ! + ! resilient compression approach is to be employed. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_set_error_resilience(bwc_field *const field); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_set_quantization_style(bwc_field *const field, bwc_quant_st quantization_style) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function amends the quantization style in the bwc_field structure according to the ! + ! specified value. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_set_quantization_style(bwc_field *const field, bwc_quant_st quantization_style); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_set_quantization_step_size(bwc_field *const field, double delta) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function amends the quantization step size in the bwc_field structure according to ! + ! the specified value. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_set_quantization_step_size(bwc_field *const field, double delta); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_set_progression(bwc_field *const field, bwc_prog_ord progression) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function amends the progression order in the bwc_field structure according to the ! + ! specified value. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_set_progression(bwc_field *const field, bwc_prog_ord progression); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_set_kernels(bwc_field *const field, bwc_dwt_filter KernelX, ! + ! -------------- bwc_dwt_filter KernelY, ! + ! bwc_dwt_filter KernelZ, ! + ! bwc_dwt_filter KernelTS) ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function amends the wavelet kernels in the bwc_field structure according to the ! + ! specified values. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_set_kernels(bwc_field *const field, bwc_dwt_filter KernelX, bwc_dwt_filter KernelY, + bwc_dwt_filter KernelZ, bwc_dwt_filter KernelTS); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_set_decomp(bwc_field *const field, uint8 decompX, uint8 decompY, ! + ! -------------- uint8 decompZ, uint8 decompTS) ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function amends the decomposition levels in the bwc_field structure according to the ! + ! specified values. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_set_decomp(bwc_field *const field, uint8 decompX, uint8 decompY, uint8 decompZ, uint8 decompTS); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_set_precincts(bwc_field *const field, uint8 pX, uint8 pY, uint8 pZ, uint8 pTS) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function amends the precinct size in the bwc_field structure according to the ! + ! specified values. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_set_precincts(bwc_field *const field, uint8 pX, uint8 pY, uint8 pZ, uint8 pTS); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_set_codeblocks(bwc_field *const field, uint8 cbX, uint8 cbY, ! + ! -------------- uint8 cbZ, uint8 cbTS) ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function amends the codeblock size in the bwc_field structure according to the ! + ! specified values. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_set_codeblocks(bwc_field *const field, uint8 cbX, uint8 cbY, uint8 cbZ, uint8 cbTS); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_set_qm(bwc_field *const field, uint8 Qm) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function amends the Q number formate range in the bwc_field structure according to the ! + ! specified value. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_set_qm(bwc_field *const field, uint8 Qm); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_set_tiles(bwc_field *const field, uint32 tilesX, uint32 tilesY, uint32 tilesZ, ! + ! -------------- uint32 tilesTS, uchar instr) ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function amends the tileSize and num_Tiles values in the bwc_field structure according ! + ! to the specified values. The NUMBEROF and SIZEOF constants can be used to either specify ! + ! the tile sizes or the number of tiles in each spatial and temporal directions. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + bwc_set_tiles(bwc_field *const field, uint64 tilesX, uint64 tilesY, uint64 tilesZ, uint16 tilesTS, bwc_tile_instr instr); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_set_nThreads(bwc_field *const field, uint16 nThreads) ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function is used to indicate the maximum number of threads used during ! + ! (de)compression. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + #if defined(_OPENMP) + void + bwc_set_nThreads(bwc_field *const field, uint8 nThreads); + #endif + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_create_compression(bwc_field *field, char *rate_control) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function creates the field structure used to compress a floating point array defined ! + ! by the bwc_initialize function. For a compression run, the rate_control and instr arguments ! + ! need to be passed to the function to properly set up the lossy compression stage. Here, the ! + ! instr parameter defines whether rate control is defined by a BITRATE - a floating point val-! + ! ue defining the average number of bits per datapoint - and ACCURACY - an integer value de- ! + ! fining the exponent of the maximum allowable error (i.e. 15 for err = 1e-15). ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + bwc_create_compression(bwc_field *field, char *rate_control); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: uchar bwc_compress(bwc_field *const field, bwc_float *const data) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! Description needed. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + bwc_compress(bwc_field *const field, bwc_data *const data); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_create_compression(bwc_field **field_ptr, char *rate_control, uchar instr) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function parses the supplied bwc codestream and sets up the field structure used to ! + ! decompress the numerical dataset. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + bwc_field * + bwc_create_decompression(bwc_data *const data, uint8 layer); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void bwc_create_compression(bwc_field **field, float rate_control, uchar instr) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function creates the field structure used to compress a floating point array defined ! + ! by the bwc_initialize function at a prescribed bitrate or accuracy. In this context, the ! + ! bitrate is a floating point value defining the average number of bits per datapoint and ! + ! the accuracy is an integer value defining the exponent of the maximum allowable error ! + ! (i.e. 15 for err = 1e-15). ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + bwc_decompress(bwc_field *const field, bwc_data *const data); +#endif \ No newline at end of file diff --git a/include/library/private/macros.h b/include/library/private/macros.h new file mode 100755 index 0000000..749d79e --- /dev/null +++ b/include/library/private/macros.h @@ -0,0 +1,140 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: macros.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| STRUCTS: || +|| -------- || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 29.05.2017 Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef BWC_MACROSS_H +#define BWC_MACROSS_H + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! These Macros are used to calculate the maximum and minimum between two values. ! + ! ! + ! Macros: ! + ! ------- ! + ! Macro Description ! + ! ----- ----------- ! + ! MAX(x, y) - Returns the maximum value of two values. ! + ! ! + ! MIN(x, y) - Returns the minimum value of two values. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 21.03.2018 Patrick Vogler B87D120 V 0.1.0 Macros created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define MAX(x, y) (((x) < (y))?(y):(x)) + #define MIN(x, y) (((x) > (y))?(y):(x)) + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! This macro is used to evaluate the size of an array. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 16.09.2019 Patrick Vogler B87D120 V 0.1.0 Macros created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define GET_DIM(x) (sizeof(x)/sizeof(*(x))) + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These Constants describe the codestream markers used to create the embedded codestream. ! + ! ! + ! CONSTANTS: ! + ! ----------- ! + ! Constant Description ! + ! -------- ----------- ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 01.12.2017 Patrick Vogler B87D120 V 0.1.0 Constants created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define MEMERROR "o##########################################################o\n"\ + "| ERROR: Out of memory |\n"\ + "o##########################################################o\n" + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These Constants describe the codestream markers used to create the embedded codestream. ! + ! ! + ! CONSTANTS: ! + ! ----------- ! + ! Constant Description ! + ! -------- ----------- ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 01.12.2017 Patrick Vogler B87D120 V 0.1.0 Constants created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define CSERROR "o##########################################################o\n"\ + "| ERROR: Invalid Codestream |\n"\ + "o##########################################################o\n" +#endif \ No newline at end of file diff --git a/include/library/private/mq.h b/include/library/private/mq.h new file mode 100755 index 0000000..8a39519 --- /dev/null +++ b/include/library/private/mq.h @@ -0,0 +1,155 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: mq.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| STRUCTS: || +|| -------- || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 13.02.2019 Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef MQ_H +#define MQ_H + + /************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************************/ + #include "types.h" + + /************************************************************************************************************\ + || ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || + || | | | |\ | [__ | |__| |\ | | [__ || + || |___ |__| | \| ___] | | | | \| | ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros define the context state indices used by the mq coder for probability estima- ! + ! tion. For a more thorough treatment of the context assignments see page 487 JPEG2000 by ! + ! David S. Taubman and Michael W. Marcellin. ! + ! ! + ! Macros: ! + ! ------- ! + ! Macro Description ! + ! ----- ----------- ! + ! CONTEXT_SIG - Starting indices for the significance context labels. ! + ! CONTEXT_RUN - Indices for the run context label. ! + ! CONTEXT_SIGN - Starting indices for the sign context labels. ! + ! CONTEXT_MAG - Starting indices for the magnitude context labels. ! + ! CONTEXT_UNI - Indices for the uni context label. ! + ! CONTEXT_TOTAL - Total number of context labels. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 21.02.2019 Patrick Vogler B87D120 V 0.1.0 Macros created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define CONTEXT_SIG 0 + #define CONTEXT_RUN 9 + #define CONTEXT_SIGN 10 + #define CONTEXT_MAG 15 + #define CONTEXT_UNI 18 + #define CONTEXT_TOTAL 19 + + /************************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! TYPE NAME: Template ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + initialize_bit_encoder(bwc_coder *const coder, const uint8 number_of_contexts); + + uchar + bit_encoder_next_run(bwc_bit_coder *const bitcoder); + + void + bit_encode(bwc_bit_coder *const bitcoder, const uint8 s, const uint8 k); + + void + bit_encoder_truncation_length_min(bwc_coder_state *const state); + + void + bit_encoder_termination(bwc_bit_coder *const bitcoder); + + void + free_bit_encoder(bwc_coder *const coder); + + uchar + initialize_bit_decoder(bwc_coder *const coder, const uint8 number_of_contexts, const int64 Lmax); + + uint8 + bit_decode(bwc_bit_coder *const bitcoder, const uint8 k); + + uint64 + bit_coder_get_no_bytes(bwc_bit_coder *const bitcoder); + + void + bit_coder_get_pass_lengths(bwc_bit_coder *const bitcoder, bwc_encoded_cblk *const encoded_cblk); + + void + bit_coder_reset_ptr(bwc_bit_coder *const bitcoder, uchar *const memory); +#endif \ No newline at end of file diff --git a/include/library/private/mq_types.h b/include/library/private/mq_types.h new file mode 100755 index 0000000..6f6a93f --- /dev/null +++ b/include/library/private/mq_types.h @@ -0,0 +1,222 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: prim_types_double.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This header defines a set of derrived types used for the mq encoder during the entropy encoding stage of the big whoop || +|| compression algorithm. || +|| || +|| STRUCTS: || +|| -------- || +|| - bwc_context_state || +|| - bwc_coder_state || +|| - bwc_bit_coder || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 20.02.2019 Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef MQ_TYPES_H +#define MQ_TYPES_H + + /************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************************/ + #include + + /************************************************************************************************************\ + || ___ ____ ____ ____ _ _ _ ____ ___ ___ _ _ ___ ____ ____ || + || | \ |___ |__/ |__/ | | | |___ | \ | \_/ |__] |___ [__ || + || |__/ |___ | \ | \ | \/ |___ |__/ | | | |___ ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_context_state ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! - ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! p unsigned int(16 bit) - LPS Probability estimate. ! + ! ! + ! sk unsigned int(8 bit) - Most Probable Symbol. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! MPS context* - New context if the coded symbol is a ! + ! Most Probable Symbol (MPS). ! + ! ! + ! LPS context* - New context if the coded symbol is a ! + ! Least Probable Symbol (LPS). ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 14.02.2019 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct context + { + uint16_t p; + uint8_t sk; + const struct context *const MPS; + const struct context *const LPS; + } bwc_context_state; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_coder_state ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! - ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! L int(64 bit) - Number of code bytes which have been ! + ! generated so far. ! + ! ! + ! C unsigned int(32 bit) - Lower bound register used to define ! + ! the lower bound of the coding interval. ! + ! ! + ! A unsigned int(16 bit) - Length register used to define the up- ! + ! bound of the coding interval. ! + ! ! + ! t int(8 bit) - Down counter which is used to evaluate ! + ! when partially generated code bits ! + ! should be moved out of the C register ! + ! in to the temporary byte buffer b. ! + ! ! + ! b unsigned char* - Byte buffer. ! + ! ! + ! T unsigned char - Temporary byte buffer. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! next state* - Coder state of the next coding pass. ! + ! ! + ! prev state* - Coder state of the previous coding ! + ! pass. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 14.02.2019 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct state + { + int64_t L; + uint32_t C; + uint16_t A; + int8_t t; + unsigned char *b; + unsigned char T; + struct state *next; + struct state *prev; + } bwc_coder_state; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_bit_coder ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! - ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! Lmax unsigned int(64 bit) - Number of code bytes (used by decoder). ! + ! ! + ! nContext unsigned int(8 bit) - Number of context states that need to ! + ! be tracked during (de)compression. ! + ! ! + ! b unsigned char* - Temporary byte buffer. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! state bwc_coder_state* - Coder state for the current coding ! + ! pass. ! + ! ! + ! context bwc_coder_state* - Context states for the current coding ! + ! pass. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 14.02.2019 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + int64_t Lmax; + uint8_t nContext; + unsigned char *b; + bwc_coder_state *state; + bwc_context_state const **context; + } bwc_bit_coder; +#endif \ No newline at end of file diff --git a/include/library/private/prim_types_double.h b/include/library/private/prim_types_double.h new file mode 100755 index 0000000..948a83b --- /dev/null +++ b/include/library/private/prim_types_double.h @@ -0,0 +1,163 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: prim_types_double.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This header defines a set of basic arithmetic types with specified widths to be used in || +|| the big whoop compression algorithm. The width of an arithmetic type is defined as the || +|| number of bits used to store its value. || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 07.12.2017 Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef BWC_PRIM_TYPES_DOUBLE_H +#define BWC_PRIM_TYPES_DOUBLE_H + + /************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************************/ + #include + + /************************************************************************************************************\ + || ___ ____ _ _ _ _ ___ _ _ _ ____ ___ _ _ ___ ____ ____ || + || |__] |__/ | |\/| | | | | | |___ | \_/ |__] |___ [__ || + || | | \ | | | | | | \/ |___ | | | |___ ___] || + || || + \************************************************************************************************************/ + typedef unsigned char uchar; + typedef unsigned short ushort; + typedef unsigned int uint; + + typedef int8_t int8; + typedef uint8_t uint8; + typedef int16_t int16; + typedef uint16_t uint16; + typedef int32_t int32; + typedef uint32_t uint32; + typedef int64_t int64; + typedef uint64_t uint64; + + typedef double bwc_float; + typedef uint64 bwc_raw; + + /************************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These constants describe the minimum and maximum values for a double precision IEEE 754 ! + ! floating point variable. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 07.12.2018 Patrick Vogler B87D120 V 0.1.0 Constants created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define FLT_MAX 1.7976931348623157e+308 + #define FLT_MIN 2.2250738585072014e-308 + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These constants describe the precision (in bits and bytes) of the primitive floating point ! + ! type used during (de)compression as well as the number of bits used to represent the ! + ! mantissa and exponent fields. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 07.12.2018 Patrick Vogler B87D120 V 0.1.0 Constants created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define PREC_BIT 63 + #define PREC_MANTISSA 52 + #define PREC_EXPONENT 11 + #define PREC_BYTE 8 + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These constants describe the bit masks used to access the sign, mantissa and exponent of ! + ! the primitive floating point type used during (de)compression. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 07.12.2018 Patrick Vogler B87D120 V 0.1.0 Constants created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define SIGN 0x8000000000000000 + #define MANTISSA 0x000FFFFFFFFFFFFF + #define EXPONENT 0x7FF0000000000000 + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This constants describe the maximum number of encoding passes during the entropy encoding ! + ! stage. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 03.07.2018 Patrick Vogler B87D120 V 0.1.0 Constants created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define MAXIMUM_NO_PASSES (64 * 3) - 2 +#endif \ No newline at end of file diff --git a/include/library/private/prim_types_single.h b/include/library/private/prim_types_single.h new file mode 100755 index 0000000..2c3872e --- /dev/null +++ b/include/library/private/prim_types_single.h @@ -0,0 +1,163 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: prim_types_single.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This header defines a set of basic arithmetic types with specified widths to be used in || +|| the big whoop compression algorithm. The width of an arithmetic type is defined as the || +|| number of bits used to store its value. || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 07.12.2017 Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef BWC_PRIM_TYPES_SINGLE_H +#define BWC_PRIM_TYPES_SINGLE_H + + /************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************************/ + #include + + /************************************************************************************************************\ + || ___ ____ _ _ _ _ ___ _ _ _ ____ ___ _ _ ___ ____ ____ || + || |__] |__/ | |\/| | | | | | |___ | \_/ |__] |___ [__ || + || | | \ | | | | | | \/ |___ | | | |___ ___] || + || || + \************************************************************************************************************/ + typedef unsigned char uchar; + typedef unsigned short ushort; + typedef unsigned int uint; + + typedef int8_t int8; + typedef uint8_t uint8; + typedef int16_t int16; + typedef uint16_t uint16; + typedef int32_t int32; + typedef uint32_t uint32; + typedef int64_t int64; + typedef uint64_t uint64; + + typedef float bwc_float; + typedef uint32 bwc_raw; + + /************************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These constants describe the minimum and maximum values for a double precision IEEE 754 ! + ! floating point variable. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 07.12.2018 Patrick Vogler B87D120 V 0.1.0 Constants created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define FLT_MAX 1.70141183e+38 + #define FLT_MIN 1.17549435e-38 + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These constants describe the precision (in bits and bytes) of the primitive floating point ! + ! type used during (de)compression as well as the number of bits used to represent the ! + ! mantissa and exponent fields. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 07.12.2018 Patrick Vogler B87D120 V 0.1.0 Constants created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define PREC_BIT 31 + #define PREC_MANTISSA 23 + #define PREC_EXPONENT 8 + #define PREC_BYTE 4 + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These constants describe the bit masks used to access the sign, mantissa and exponent of ! + ! the primitive floating point type used during (de)compression. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 07.12.2018 Patrick Vogler B87D120 V 0.1.0 Constants created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define SIGN 0x80000000 + #define MANTISSA 0x007FFFFF + #define EXPONENT 0x7F800000 + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This constants describe the maximum number of encoding passes during the entropy encoding ! + ! stage. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 03.07.2018 Patrick Vogler B87D120 V 0.1.0 Constants created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define MAXIMUM_NO_PASSES (32 * 3) - 2 +#endif \ No newline at end of file diff --git a/include/library/private/tagtree.h b/include/library/private/tagtree.h new file mode 100755 index 0000000..4451388 --- /dev/null +++ b/include/library/private/tagtree.h @@ -0,0 +1,161 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: tagtree.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| STRUCTS: || +|| -------- || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 18.05.2018 Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef TAGTREE_H +#define TAGTREE_H + + /************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************************/ + #include "types.h" + + /************************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void kill_tagtree(bwc_tagtree* tagtree) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function deallocates a tagtree instance used to encode codeblock contributions to a ! + ! specific quality layer as well as the number of magnitude bit planes used to represent the ! + ! samples of a specific codeblock. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + kill_tagtree(bwc_tagtree* tagtree); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + reset_tagtree(bwc_tagtree* const tagtree); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uint16 + tagtree_get_value(const bwc_tagtree* const tagtree, const uint64 leaf_index); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + tagtree_set_value(bwc_tagtree* const tagtree, const uint64 leaf_index, const uint16 value); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + bwc_tagtree* + initialize_tagtree(const uint64 leafsX, const uint64 leafsY, const uint64 leafsZ, const uint64 leafsTS); + + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + void + encode_tagtree(bwc_tagtree *const tagtree, bwc_stream *const stream, const uint32 threshold, const uint32 leaf_index, const uchar estimate); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: void *test(void) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + decode_tagtree(bwc_tagtree *const tagtree, bwc_stream *const stream, const uint32 threshold, const uint32 leaf_index); +#endif \ No newline at end of file diff --git a/include/library/private/tier1.h b/include/library/private/tier1.h new file mode 100755 index 0000000..7526caa --- /dev/null +++ b/include/library/private/tier1.h @@ -0,0 +1,153 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: tier1.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| STRUCTS: || +|| -------- || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| - Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef TIER1_H +#define TIER1_H + + /************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************************/ + #include "types.h" + + /************************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This macro defines the maximum decomposition level up to which the wavelet filer energy gain ! + ! is calculated. Beyond the maximum decomposition level the energy gain will only be ! + ! approximated. ! + ! ! + ! Macros: ! + ! ------- ! + ! Macro Description ! + ! ----- ----------- ! + ! MAX_DECOMPOSITION_LEVELS - Maximum number of wavelet layers for which the energy ! + ! gain is calculated. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 20.03.2018 Patrick Vogler B87D120 V 0.1.0 Macros created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define DISTORTION_DELTA 0.5f + #define DISTORTION_MANTISSA 5 + #define DISTORTION_PRECISION 6 + + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros define the irrational coefficients for the high and low pass synthesis filters ! + ! associated with the (5-3) LeGall-Wavelet. ! + ! ! + ! Macros: ! + ! ------- ! + ! Macro Description ! + ! ----- ----------- ! + ! DWT_5X3_H0 - Coefficients for the (9-7) ! + ! DWT_5X3_H1 low pass synthesis filter. ! + ! ! + ! DWT_5X3_G0 ! + ! DWT_5X3_G1 - Coefficients for the (9-7) ! + ! DWT_5X3_G2 high pass synthesis filter. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 20.03.2018 Patrick Vogler B87D120 V 0.1.0 Macros created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define DWT_5X3_H0 1.0f + #define DWT_5X3_H1 0.5f + + #define DWT_5X3_G0 0.75f + #define DWT_5X3_G1 -0.25f + #define DWT_5X3_G2 -0.125f + + /************************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! TYPE NAME: Template ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + t1_encode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const parameter); + + uchar + t1_decode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const parameter); +#endif \ No newline at end of file diff --git a/include/library/private/tier2.h b/include/library/private/tier2.h new file mode 100755 index 0000000..d853bfe --- /dev/null +++ b/include/library/private/tier2.h @@ -0,0 +1,133 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: tier2.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| STRUCTS: || +|| -------- || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| - t2_encode || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| - Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef TIER2_H +#define TIER2_H + + /************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************************/ + #include "types.h" + + /************************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This macro defines the initial packet header size. ! + ! ! + ! Macros: ! + ! ------- ! + ! Macro Description ! + ! ----- ----------- ! + ! PACKET_HEADER_SIZE - Initial packet header size. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 10.05.2019 Patrick Vogler B87D120 V 0.1.0 Macros created ! + \*----------------------------------------------------------------------------------------------------------*/ + #define PACKET_HEADER_SIZE 512 + + /************************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: uchar t2_encode(bwc_field *const field, bwc_tile *const tile) ! + ! -------------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function defines the rate control portion of the entropy encoding stage. In ! + ! the first step, the quality layers are evaluated according to the bitrates de- ! + ! fined by the user. The quality layers are then used to create the data packets ! + ! that comprise the bwc codestream. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + t2_encode(bwc_field *const field, bwc_tile *const tile); + + /*----------------------------------------------------------------------------------------------------------*\ + ! FUNCTION NAME: uchar parse_packet(bwc_field *const field, bwc_tile *const tile, ! + ! -------------- bwc_packet *const packet, ! + ! uint64 const body_size) ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function is used to parse a codestream packet for a given precinct (prec_idx) ! + ! and quality layer (q_layer). ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + uchar + parse_packet(bwc_field *const field, bwc_tile *const tile, + bwc_packet *const packet, + uint64 const body_size); +#endif \ No newline at end of file diff --git a/include/library/private/types.h b/include/library/private/types.h new file mode 100755 index 0000000..e41fa35 --- /dev/null +++ b/include/library/private/types.h @@ -0,0 +1,1805 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| File: types.h || +|| ----- || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This header defines a set of basic arithmetic types with specified widths to be used in the big whoop compression || +|| algorithm. The width of an arithmetic type is defined as the number of bits used to store its value. || +|| || +|| STRUCTS: || +|| -------- || +|| - IEEE_754_Double_Prec || +|| - bwc_sample || +|| - bwc_cblk_ctrl || +|| - bwc_cblk_inf || +|| - bwc_codeblock || +|| - bwc_prec_ctrl || +|| - bwc_prec_inf || +|| - bwc_precinct || +|| - bwc_subb_ctrl || +|| - bwc_subb_inf || +|| - bwc_subband || +|| - bwc_res_ctrl || +|| - bwc_res_inf || +|| - bwc_resolution || +|| - bwc_param_ctrl || +|| - bwc_param_inf || +|| - bwc_parameter || +|| - bwc_tile_ctrl || +|| - bwc_tile_inf || +|| - bwc_tile || +|| - bwc_mpi_ctrl || +|| - bwc_gl_ctrl || +|| - bwc_cmd_opts_ll || +|| - bwc_gl_inf || +|| - bwc_field || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 10.10.2017 Patrick Vogler B87D120 V 0.1.0 header file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +#ifndef BWC_TYPES_H +#define BWC_TYPES_H + + #include + /************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************************/ + #ifdef BWC_SINGLE_PRECISION + #include "prim_types_single.h" + #else + #include "prim_types_double.h" + #endif + + #include "constants.h" + #include "mq_types.h" + + /************************************************************************************************************\ + || ___ ____ ____ ____ _ _ _ ____ ___ ___ _ _ ___ ____ ____ || + || | \ |___ |__/ |__/ | | | |___ | \ | \_/ |__] |___ [__ || + || |__/ |___ | \ | \ | \/ |___ |__/ | | | |___ ___] || + || || + \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! UNION NAME: bwc_sample ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This union holds a floating point sample of the uncompressed data set and allows access to ! + ! its raw bit representation. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! raw bwc_raw - Raw access to the data sample. ! + ! ! + ! f bwc_float - Floating point representation of the ! + ! data sample. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 11.10.2017 Patrick Vogler B87D120 V 0.1.0 union created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef union + { + bwc_raw raw; + bwc_float f; + } bwc_sample; + + /*----------------------------------------------------------------------------------------------------------*\ + | ___ _ ___ ____ ___ ____ ____ ____ _ _ | + | |__] | | [__ | |__/ |___ |__| |\/| | + | |__] | | ___] | | \ |___ | | | | | + | | + \*----------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_packed_stream ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure is used to store the reading/writing position, overall size and memory ! + ! handle of a packed stream. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! position unsigned int(32 bit) - Reading/Writing position in the packed ! + ! stream. ! + ! ! + ! size unsigned int(32 bit) - Size of packed stream. ! + ! ! + ! access unsigned char* - Memory handle used to parse the paced ! + ! stream. ! + ! ! + ! memory unsigned char* - Memory handle for the packed stream. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 12.04.2019 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 position; + uint64 size; + uchar *access; + uchar *memory; + } bwc_packed_stream; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_stream ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 28.05.2018 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 L; + uint64 Lmax; + uint64 size_incr; + uint8 T; + int8 t; + uchar error; + uchar *memory; + } bwc_stream; + + /*----------------------------------------------------------------------------------------------------------*\ + | ____ _ _ ____ ____ ___ ____ ____ | + | |___ |\ | | | | | \ |___ |__/ | + | |___ | \| |___ |__| |__/ |___ | \ | + | | + \*----------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_coder_stripe ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds the sign, bitfield and state information for two vertically adjacent ! + ! sample stripes for easy access during the entropy encoding stage. To facilitate distortion ! + ! estimation the magnitude of the wavelet coefficients is stored in an appropriate sample ! + ! array. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! sample unsigned int*(64 bit) - Array holding two vertically adjacent ! + ! wavelet coefficient stripes. ! + ! ! + ! sigma_u, _r, _d, _l unsigned int*(16 bit) - Pointer used to hold the address of the ! + ! sample states for the upper (_u), right ! + ! (_r), lower (_d) and left (_l) neighbor ! + ! wavelet coefficient stripe. ! + ! ! + ! sigma unsigned int(16 bit) - Sample states for the two vertically ! + ! adjacent wavelet coefficient stripes. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 15.11.2018 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct stripe{ + uint64 *sample; + uint8 codingpass; + uint8 delta; + uint8 sigma; + uint8 bitplane; + uint8 pi; + uint8 xi; + uint8 *bit; + struct stripe *stripe_u; + struct stripe *stripe_r; + struct stripe *stripe_d; + struct stripe *stripe_l; + } bwc_coder_stripe; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_coder ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure defines a single tagtree node which stores the node value, node threshold as ! + ! well as the address of the parent node. The tagtree node structure is used in conjuncture ! + ! with a bwc_tagtree instance to define a tagtree. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 buff_incr, buff_size; + uint64 no_full_stripe, no_slice; + uint64 width, height; + uint8 K; + uint8 const *sig2context; + uchar erres; + uchar highband_flag; + uchar *compressed; + bwc_bit_coder *bitcoder; + bwc_coder_stripe *data; + } bwc_coder; + + /*----------------------------------------------------------------------------------------------------------*\ + | ___ ____ ____ ___ ____ ____ ____ | + | | |__| | __ | |__/ |___ |___ | + | | | | |__] | | \ |___ |___ | + | | + \*----------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_tagtree_node ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure defines a single tagtree node which stores the node value, node threshold as ! + ! well as the address of the parent node. The tagtree node structure is used in conjuncture ! + ! with a bwc_tagtree instance to define a tagtree. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! value unsigned int(16 bit) - Tagtree node value. ! + ! ! + ! threshold unsigned int(16 bit) - Tagtree node threshold. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! parent node* - Address of the parent node. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.05.2018 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct node + { + uint64 index; + uint16 value; + uint16 threshold; + struct node* parent; + } bwc_tagtree_node; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_tagtree ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure defines a tagtree instance which stores the number of spatial and temporal ! + ! tagtree leafs as well as the tagtree itself defined by a bwc_tagtree_node linked list. ! + ! The tagtree structure ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! leavesX ,leavesY, leavesZ unsigned int(64 bit) - Variables defining the number of spa- ! + ! tial tagtree leafs. ! + ! ! + ! leavesTS unsigned int(64 bit) - Variable defining the number of tempo- ! + ! ral tagtree leafs. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! nodes bwc_tagtree_node* - Linked list storing the tagtree values ! + ! and thresholds. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 10.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 leavesX, leavesY, leavesZ; + uint64 leavesTS; + bwc_tagtree_node *nodes; + } bwc_tagtree; + + /*----------------------------------------------------------------------------------------------------------*\ + | ___ ____ ___ ____ ____ ____ ___ | + | | \ |__| | |__| [__ |___ | | + | |__/ | | | | | ___] |___ | | + | | + \*----------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_cmd_opts_ll ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure defines a linked list which stores a parameters name, its index, bit preci- ! + ! sion, sampling factor and the dimension for which the sampling is active. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! size unsigned int(64 bit) - Size of parameter after sub-sampling. ! + ! ! + ! id unsigned int(8 bit) - Index of the parameter. ! + ! ! + ! precision unsigned int(8 bit) - Defines the precision of a compressed ! + ! dataset. ! + ! ! + ! sample unsigned int(8 bit) - Sampling factor for parameter(id). ! + ! ! + ! name char - Defines the name of parameter(id). ! + ! ! + ! dim unsigned char - Dimension(s) for which the sampling ! + ! factor is active. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! next opt* - Address for the next linked list node. ! + ! ! + ! root opt* - Address for the root linked list node. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 04.12.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! 05.12.2019 Patrick Vogler B87E7E4 V 0.1.0 Removal of unecessary parameters. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct opt + { + uint64 size; + uint8 id; + uint8 precision; + uint8 sample; + uchar dim; + char name[24]; + struct opt *next; + struct opt *root; + } bwc_cmd_opts_ll; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_gl_inf ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the global information of the uncompressed data set including its ! + ! spatial and temporal dimensions, number of parameters, its bit-depth precision and all the ! + ! parameter information. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! nX ,nY, nZ unsigned int(64 bit) - Variables defining the spatial size of ! + ! the uncompressed dataset. ! + ! ! + ! nTS unsigned int(16 bit) - Variable defining the temporal size of ! + ! the uncompressed dataset. ! + ! ! + ! nPar unsigned int(8 bit) - Defines the number of parameters in the ! + ! uncompressed dataset. ! + ! ! + ! precision unsigned int(8 bit) - Flag used to signal the encoder/decoder ! + ! precision. ! + ! ! + ! f_ext uchar* - Character array used to hold the file ! + ! extension ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! parameter bwc_cmd_opts_ll* - Linked list storing the parameter names,! + ! indices, sampling factors and active ! + ! dimensions. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 10.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! 05.12.2019 Patrick Vogler B87E7E4 V 0.1.0 Removal of unecessary parameters. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 nX, nY, nZ; + uint16 nTS; + uint8 nPar; + uint8 precision; + char f_ext[20]; + bwc_cmd_opts_ll *parameter; + } bwc_gl_inf; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_data ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure stores the numerical dataset/compressed bitstream passed to or returned ! + ! from the (de)compressor. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! field field - Structure that holds the single (f) or ! + ! double (d) precission parameters of a ! + ! numerical dataset. ! + ! ! + ! file file - Structure that holds the file pointer ! + ! and memory handle for single (f) or ! + ! double (d) precission parameters of a ! + ! numerical dataset. ! + ! ! + ! codestream codestream - Structure that holds the packed data, ! + ! auxiliary information (aux) and com- ! + ! ment stream of a compressed dataset. ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! info bwc_gl_inf* - Structure holding all the global infor- ! + ! mation of the uncompressed data set. ! + ! ! + ! data bwc_packed_stream* - Stream holding the data memory block. ! + ! ! + ! aux bwc_packed_stream* - Stream holding the auxiliary informa- ! + ! tion memory block. ! + ! ! + ! com bwc_packed_stream* - Stream holding the commentary memory ! + ! block. ! + ! ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 17.04.2019 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! 04.12.2019 Patrick Vogler B87E7E4 V 0.1.0 Cleaned up the structure and added ! + ! functionality to store both single ! + ! and double precision datasets. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_gl_inf info; + + struct codestream + { + bwc_packed_stream *data; + bwc_packed_stream *aux; + bwc_packed_stream *com; + }codestream; + + struct field + { + double *d; + float *f; + }field; + + struct file + { + FILE *fp; + uint64 *d_root; + uint64 *f_root; + }file; + } bwc_data; + + /*----------------------------------------------------------------------------------------------------------*\ + | ____ ____ _ _ ___ ____ ____ ____ ____ _ ____ _ _ | + | | | | |\/| |__] |__/ |___ [__ [__ | | | |\ | | + | |___ |__| | | | | \ |___ ___] ___] | |__| | \| | + | | + \*----------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_encoded_block ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the necessary parameters used to define and control a bwc ! + ! codeblock. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! info bwc_cblk_inf* - Structure holding all the codeblock in- ! + ! formation. ! + ! ! + ! control bwc_cblk_ctrl* - Structure holding all the codeblock ! + ! control parameters. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 L[MAXIMUM_NO_PASSES]; + uint16 S[MAXIMUM_NO_PASSES + 1]; + uint8 Kmsbs; + uint8 K; + uint8 Z; + uchar *data; + } bwc_encoded_cblk; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_cblk_ctrl ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the control parameters for the current codeblock used to instruct ! + ! the bwc codec to (de)compress a floating point array. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint16 beta; + uint16 beta_est; + uint16 K; + int16 *cp_contr; + int16 *memory; + } bwc_cblk_ctrl; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_cblk_inf ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds the dimensions for the current codeblock. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! X0, Y0, Z0, TS0 unsigned int(32 bit) - Variables defining the spatial starting ! + ! point of a codeblock. ! + ! ! + ! X1, Y1, Z1, TS1 unsigned int(32 bit) - Variables defining the spatial end ! + ! point of a codeblock. ! + ! ! + ! idx unsigned int(32 bit) - Variable defining codeblock index in ! + ! the current precinct. ! + ! ! + ! TS0 unsigned int(16 bit) - Variable defining the temporal start- ! + ! ing point of a codeblock. ! + ! ! + ! TS1 unsigned int(16 bit) - Variable defining the temporal end ! + ! point of a codeblock. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 X0, Y0, Z0; + uint64 X1, Y1, Z1; + uint32 idx; + uint16 TS0; + uint16 TS1; + } bwc_cblk_inf; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_codeblock ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the necessary parameters used to define and control a bwc ! + ! codeblock. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! info bwc_cblk_inf* - Structure holding all the codeblock in- ! + ! formation. ! + ! ! + ! control bwc_cblk_ctrl* - Structure holding all the codeblock ! + ! control parameters. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_cblk_inf info; + bwc_cblk_ctrl control; + bwc_encoded_cblk *encoded_block; + } bwc_codeblock; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_prec_ctrl ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the control parameters for the current precinct used to instruct ! + ! the bwc codec to (de)compress a floating point array. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! number_of_codeblocks unsigned int(64 bit) - Defines the number of codeblocks for ! + ! the current resolution level. ! + ! ! + ! numPX, -PY, -PZ, -PTS unsigned int(16 bit) - Variables defining the number of code- ! + ! blocks for the current resolution level ! + ! in all spatial and temporal directions. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! tag_inclusion bwc_tagtree* - Tagtree identifying wether the current ! + ! codeblock contributes to a specific ! + ! quality layer. ! + ! ! + ! tag_msbs bwc_tagtree* - Tagtree identifying the number of mag- ! + ! nitude bit planes used to represent the ! + ! samples of the current codeblock. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 number_of_codeblocks; + uint16 numCbX, numCbY, numCbZ, numCbTS; + bwc_tagtree *tag_inclusion; + bwc_tagtree *tag_msbs; + } bwc_prec_ctrl; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_prec_inf ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds the dimensions for the current precinct. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! X0, Y0, Z0, TS0 unsigned int(32 bit) - Variables defining the spatial starting ! + ! point of a precinct. ! + ! ! + ! X1, Y1, Z1, TS1 unsigned int(32 bit) - Variables defining the spatial end ! + ! point of a precinct. ! + ! ! + ! TS0 unsigned int(16 bit) - Variables defining the temporal start- ! + ! ing point of a precinct. ! + ! ! + ! TS1 unsigned int(16 bit) - Variables defining the temporal end ! + ! point of a precinct. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint32 X0, Y0, Z0; + uint32 X1, Y1, Z1; + uint16 TS0; + uint16 TS1; + } bwc_prec_inf; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_precinct ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the necessary parameters used to define and control a bwc ! + ! precinct. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! info bwc_prec_inf* - Structure holding all the precinct in- ! + ! formation. ! + ! ! + ! control bwc_prec_ctrl* - Structure holding all the precinct con- ! + ! trol parameters. ! + ! ! + ! codeblock bwc_codeblock* - Structure defining a bwc codeblock. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_prec_inf info; + bwc_prec_ctrl control; + bwc_codeblock *codeblock; + } bwc_precinct; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_subb_ctrl ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the control parameters for the current subband used to instruct ! + ! the bwc codec to (de)compress a floating point array. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! Kmax unsigned int(16 bit) - Defines the dynamic range of the cur- ! + ! rent subband after transformation. ! + ! ! + ! qt_mantissa unsigned int(16 bit) - Defines the mantissa of the subband ! + ! quantisation step size. ! + ! ! + ! qt_exponent unsigned int(8 bit) - Defines the exponent of the subband ! + ! quantisation step size. ! + ! ! + ! highband_flag unsigned char - Defines the type of highband the cur- ! + ! rent subband represents. ! + ! ! + ! qt_effective_step_size bwc_float - Defines the effective quantization step ! + ! size for the current subband. ! + ! ! + ! qt_step_size bwc_float - Defines the quantization step size for ! + ! the current subband. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint16 Kmax; + uint16 qt_mantissa; + uint8 qt_exponent; + uchar highband_flag; + bwc_float qt_effective_step_size; + bwc_float qt_step_size; + } bwc_subb_ctrl; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_subb_inf ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds the dimensions and the energy gain factor for the current subband. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! X0, Y0, Z0, TS0 unsigned int(64 bit) - Variables defining the spatial starting ! + ! point of a subband. ! + ! ! + ! X1, Y1, Z1, TS1 unsigned int(64 bit) - Variables defining the spatial end ! + ! point of a subband. ! + ! ! + ! TS0 unsigned int(16 bit) - Variables defining the temporal start- ! + ! ing point of a subband. ! + ! ! + ! TS1 unsigned int(16 bit) - Variables defining the temporal end ! + ! point of a subband. ! + ! ! + ! dwt_gain bwc_float - Defines the energy gain factor for the ! + ! current subband. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 X0, Y0, Z0; + uint64 X1, Y1, Z1; + uint16 TS0; + uint16 TS1; + bwc_float dwt_gain; + } bwc_subb_inf; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_subband ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the necessary parameters used to define and control a bwc subband. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! info bwc_subb_inf* - Structure holding all the subband in- ! + ! formation. ! + ! ! + ! control bwc_subb_ctrl* - Structure holding all the subband con- ! + ! trol parameters. ! + ! ! + ! precinct bwc_precinct* - Structure defining a bwc precinct. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_subb_inf info; + bwc_subb_ctrl control; + bwc_precinct *precinct; + } bwc_subband; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_packet ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds the position of the current packet in the compressed bitstream, the ! + ! total number of bytes occupied by the packet as well as the packed codestreams of the pack- ! + ! et body and header. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! size unsigned int(64 bit) - Overall size of the codestream packet. ! + ! e unsigned int(8 bit) - Identifier used as an indicator if no ! + ! codeblock contributions are present in ! + ! current packet. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! body bwc_packed_stream - Structure holding the packed codestream ! + ! of the current packet body. ! + ! ! + ! header bwc_packed_stream - Structure holding the packed codestream ! + ! of the current packet header. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint32 size; + uint32 p; + uint8 e; + uint8 c, l, r; + bwc_packed_stream body; + bwc_packed_stream header; + } bwc_packet; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_res_ctrl ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the control parameters for the current resolution level used to ! + ! instruct the bwc codec to (de)compress a floating point array. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! number_of_precincts unsigned int(64 bit) - Defines the number of precincts for the ! + ! current resolution level. ! + ! ! + ! numPX, -PY, -PZ, -PTS unsigned int(16 bit) - Variables defining the number of pre- ! + ! cinct for the current resolution level ! + ! in all spatial and temporal directions. ! + ! ! + ! number_of_subbands unsigned int(8 bit) - Defines the number of subbands for the ! + ! current resolution level. ! + ! ! + ! rcbX, rcbY, rcbZ, rcbTS unsigned int(8 bit) - Variables defining the real codeblock ! + ! size for the current resolution level. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 number_of_precincts; + uint16 numPX, numPY, numPZ, numPTS; + uint8 number_of_subbands; + uint8 rcbX, rcbY, rcbZ, rcbTS; + } bwc_res_ctrl; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_res_inf ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds the dimensions for the current resolution level. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! X0, Y0, Z0, TS0 unsigned int(64 bit) - Variables defining the spatial starting ! + ! point of a resolution level. ! + ! ! + ! X1, Y1, Z1, TS1 unsigned int(64 bit) - Variables defining the spatial end ! + ! point of a resolution level. ! + ! ! + ! TS0 unsigned int(16 bit) - Variables defining the temporal start- ! + ! ing point of a resolution level. ! + ! ! + ! TS1 unsigned int(16 bit) - Variables defining the temporal end ! + ! point of a resolution level. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 X0, Y0, Z0; + uint64 X1, Y1, Z1; + uint16 TS0; + uint16 TS1; + } bwc_res_inf; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_resolution ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the necessary parameters used to define and control a bwc resolu- ! + ! tion level. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! info bwc_res_inf* - Structure holding all the resolution ! + ! level information. ! + ! ! + ! control bwc_res_ctrl* - Structure holding all the resolution ! + ! level control parameters. ! + ! ! + ! subband bwc_subband* - Structure defining a bwc subband. ! + ! ! + ! packet bwc_packet** - Structure defining a bwc packet. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 23.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_res_inf info; + bwc_res_ctrl control; + bwc_subband *subband; + bwc_packet *packet; + } bwc_resolution; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_cblk_access ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure is used to directly access the parameter codeblocks during entropy de-/ ! + ! encoding to facilitate shared memory parallelization. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! codeblock bwc_codeblock* - Structure defining a bwc codeblock. ! + ! ! + ! precinct bwc_precinct* - Structure defining a bwc precinct. ! + ! ! + ! subband bwc_subband* - Structure defining a bwc subband. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 17.10.2018 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_codeblock *codeblock; + bwc_precinct *precinct; + bwc_subband *subband; + } bwc_cblk_access; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_param_ctrl ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the control parameters for the current tile param. used to in- ! + ! struct the bwc codec to (de)compress a floating point array. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! number_of_codeblocks unsigned int(64 bit) - Defines the number of codeblocks for ! + ! the current tile parameter. ! + ! ! + ! sampX, sampY, sampZ unsigned int(8 bit) - Variables defining the spatial sub- ! + ! sampling value. ! + ! ! + ! sampT unsigned int(8 bit) - Defines the temporal subsampling value. ! + ! ! + ! alpha, beta bwc_float - Parameters used to normalized the cur- ! + ! rent tile parameter. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 11.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 number_of_codeblocks; + uint8 sampX, sampY, sampZ; + uint8 sampTS; + bwc_float alpha, beta; + } bwc_param_ctrl; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_param_inf ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds the dimensions, name and maximum exponent for the current tile param- ! + ! eter of the uncompressed data set. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! X0, Y0, Z0, TS0 unsigned int(64 bit) - Variables defining the spatial starting ! + ! point of a tile parameter. ! + ! ! + ! X1, Y1, Z1, TS1 unsigned int(64 bit) - Variables defining the spatial end ! + ! point of a tile parameter. ! + ! ! + ! TS0 unsigned int(16 bit) - Variables defining the temporal start- ! + ! ing point of a tile parameter. ! + ! ! + ! TS1 unsigned int(16 bit) - Variables defining the temporal end ! + ! point of a tile parameter. ! + ! ! + ! parameter_max bwc_float - Defines the maximum value of the corre- ! + ! sponding parameter. ! + ! ! + ! parameter_min bwc_float - Defines the minimum value of the corre- ! + ! sponding parameter. ! + ! ! + ! parameter_name char - Defines the name of the corresponding ! + ! parameter. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 11.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 size; + uint64 X0, Y0, Z0; + uint64 X1, Y1, Z1; + uint16 TS0; + uint16 TS1; + uint8 precision; + bwc_float parameter_max; + bwc_float parameter_min; + char *name; + } bwc_param_inf; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_parameter ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the necessary parameters used to define and control the (de)com- ! + ! pression of a bwc tile parameter. Furthermore, this structure stores the uncompressed ! + ! floating point dataset pertaining to the tile parameter. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! info bwc_param_inf* - Structure holding all the tile param- ! + ! eter information of the uncompressed ! + ! data set. ! + ! ! + ! control bwc_param_ctrl* - Structure holding all the tile param- ! + ! control parameters for the bwc codec. ! + ! ! + ! resolution bwc_resolution* - Structure defining a bwc resolution ! + ! level. ! + ! ! + ! access bwc_cblk_access* - Structure used to directly access the ! + ! parameter codeblocks during the entropy ! + ! de-/encoding. ! + ! ! + ! data bwc_sample* - Structure holding the uncompressed data ! + ! set pertaining to the tile parameter. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 11.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_param_inf info; + bwc_param_ctrl control; + bwc_cblk_access *access; + bwc_resolution *resolution; + bwc_sample *data; + } bwc_parameter; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_tile_ctrl ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the control parameters for the current tile used to instruct the ! + ! bwc codec to (de)compress a floating point array. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! body_size unsigned int(64 bit) - Defines the size of the tile parameter ! + ! body. ! + ! ! + ! Ltp unsigned int(64 bit) - Tile part size. ! + ! ! + ! header_size unsigned int(32 bit) - Defines the approximate size of the ! + ! tile parameter header. ! + ! ! + ! nPackets unsigned int(32 bit) - Number of packets assembled for the ! + ! current tile. ! + ! ! + ! max_Prec unsigned int(32 bit) - Defines the maximum number of precincts ! + ! between all tile parameters. ! + ! ! + ! dflt_param_c, dflt_param_q unsigned int(16 bit) - Variables defining the default param- ! + ! eter index to use when writing COD (c) ! + ! or QCD (q) in main header. ! + ! ! + ! slope_min, slope_max unsigned int(16 bit) - Defines the minimum and maximum value ! + ! for the convex hull slope threshold. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 11.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 body_size; + uint64 Ltp; + uint32 header_size; + uint32 nPackets; + uint32 max_Prec; + uint16 dflt_param_c, dflt_param_q; + uint16 slope_min, slope_max; + } bwc_tile_ctrl; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_tile_inf ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds the dimensions for the current tile of the uncompressed data set. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! size unsigned int(64 bit) - Variable defining the size of a tile ! + ! ! + ! X0, Y0, Z0, TS0 unsigned int(64 bit) - Variables defining the spatial starting ! + ! point of a tile. ! + ! ! + ! X1, Y1, Z1, TS1 unsigned int(64 bit) - Variables defining the spatial end ! + ! point of a tile. ! + ! ! + ! tile_index unsigned int(32 bit) - Index used to uniquely identify a tile. ! + ! ! + ! TS0 unsigned int(16 bit) - Variables defining the temporal start- ! + ! ing point of a tile. ! + ! ! + ! TS1 unsigned int(16 bit) - Variables defining the temporal end ! + ! point of a tile. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 11.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 size; + uint64 X0, Y0, Z0; + uint64 X1, Y1, Z1; + uint32 tile_index; + uint16 TS0; + uint16 TS1; + } bwc_tile_inf; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_tile ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the necessary parameters used to define and control the (de)com- ! + ! pression of a bwc tile. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! - - - ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! info bwc_tile_inf* - Structure holding all the tile infor- ! + ! mation of the uncompressed data set. ! + ! ! + ! control bwc_tile_ctrl* - Structure holding all the tile control ! + ! ! + ! parameter bwc_parameter* - Structure defining a bwc tile parameter.! + ! ! + ! packet_sequence bwc_packet** - Array of pointers used to sequence the ! + ! codestream packets. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 11.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_tile_inf info; + bwc_tile_ctrl control; + bwc_parameter *parameter; + bwc_packet **packet_sequence; + } bwc_tile; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_gl_ctrl ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the global control parameters used to instruct the bwc codec to ! + ! (de)compress a floating point array. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! tileSizeX, -Y, -Z unsigned int(64 bit) - Variables defining spatial size of a ! + ! tile. ! + ! ! + ! nTiles unsigned int(32 bit) - Defines the global number of tiles. ! + ! ! + ! qt_exponent unsigned int(32 bit) - Defines the exponent of the global ! + ! quantisation step size. ! + ! ! + ! qt_mantissa unsigned int(32 bit) - Defines the mantissa of the global ! + ! quantisation step size. ! + ! ! + ! CSsgc unsigned int(16 bit) - Variable used to keep track which con- ! + ! trol parameter was set by the user. ! + ! ! + ! tileSizeTS unsigned int(16 bit) - Defines the max temporal size of a ! + ! parameter tile. ! + ! ! + ! tileSizeTS unsigned int(16 bit) - Defines the temporal size of a tile. ! + ! ! + ! cbX, cbY, cbZ, cbTS unsigned int(8 bit) - Variables defining spatial and temporal ! + ! codeblock size in log2 exponent format. ! + ! ! + ! ! + ! decompX, decompY, decompZ unsigned int(8 bit) - Variables defining the number of spa- ! + ! tial wavelet decompositions used during ! + ! compression. ! + ! ! + ! decompTS unsigned int(8 bit) - Defines the number of temporal wavelet ! + ! decompositions used during compression. ! + ! ! + ! guard_bits unsigned int(8 bit) - Defines the number of guard bit used ! + ! during quantization. ! + ! ! + ! number_of_decomp unsigned int(8 bit) - Defines the global number of wavelet ! + ! decomposition levels. ! + ! ! + ! number_of_layers unsigned int(8 bit) - Defines the number of quality layers ! + ! used during (de)compression. ! + ! ! + ! Qm unsigned int(8 bit) - Defines the Q number format range (m). ! + ! ! + ! quantization_step_size double - Defines the global quantization step ! + ! size. ! + ! ! + ! bitrate float* - Defines the average number of bits per ! + ! datapoint after compression. ! + ! ! + ! error_resilience char - Specifies if an error resilient comp. ! + ! approach is employed. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! KernelX, KernelY, KernelZ bwc_dwt_filter - Specifies the wavelet kernels used for ! + ! spatial decomposition. ! + ! ! + ! KernelT bwc_dwt_filter - Specifies the wavelet kernel used for ! + ! temporal decomposition. ! + ! ! + ! header bwc_header* - Defines the main header stream. ! + ! ! + ! progression bwc_prog_ord - Specifies which of the five progression ! + ! orders is employed (CPRL, LRCP, PCRL, ! + ! RLCP, RPCL). ! + ! ! + ! quantization_style bwc_quant_st - Specifies which of the two quantization ! + ! styles is employed (none, derived). ! + ! ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 10.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 tileSizeX, tileSizeY, tileSizeZ; + uint32 nTiles; + uint32 qt_exponent; + uint32 qt_mantissa; + uint16 CSsgc; + uint16 tileSizeTS; + uint8 cbX, cbY, cbZ, cbTS; + uint8 decompX, decompY, decompZ, decompTS; + uint8 guard_bits; + uint8 nDecomp; + uint8 nLayers, useLayer; + uint8 precSizeX, precSizeY, precSizeZ, precSizeTS; + uint8 Qm; + float *bitrate; + uchar error_resilience; + bwc_dwt_filter KernelX, KernelY, KernelZ; + bwc_dwt_filter KernelTS; + bwc_packed_stream header; + bwc_prog_ord progression; + bwc_quant_st quantization_style; + #ifdef _OPENMP + uint8 nThreads; + #endif + } bwc_gl_ctrl; + + /*----------------------------------------------------------------------------------------------------------*\ + ! STRUCT NAME: bwc_field ! + ! ----------- ! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the necessary parameters used to define and control the bwc codec ! + ! to (de)compress a floating point array. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! codec char - Determines wether current field struc- ! + ! is defined for a compression or decom- ! + ! pression stage. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Variable Type Description ! + ! -------- ---- ----------- ! + ! info bwc_gl_inf* - Structure holding all the global infor- ! + ! mation of the uncompressed data set. ! + ! ! + ! control bwc_gl_ctrl* - Structure holding all the global con- ! + ! trol parameters for the bwc codec. ! + ! ! + ! tile bwc_tile* - Structure holding defining a bwc tile ! + ! ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description Of Change ! + ! ---- ------ --------- ------- --------------------- ! + ! 10.10.2017 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! 05.12.2019 Patrick Vogler B87E7E4 V 0.1.0 Removal of unecessary parameters. ! + ! ! + \*----------------------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_gl_inf *info; + bwc_gl_ctrl control; + bwc_tile *tile; + + struct meter + { + double bpd; + double cpr; + double css; + + struct time + { + double ttl; + + double cpy; + double nrm; + + double wav; + double ent; + double ass; + } time; + } meter; + } bwc_field; +#endif \ No newline at end of file diff --git a/include/tools/bwccmdl.h b/include/tools/bwccmdl.h new file mode 100644 index 0000000..be53e0b --- /dev/null +++ b/include/tools/bwccmdl.h @@ -0,0 +1,350 @@ +/*====================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This is a simple command line tool that uses the Big Whoop library to (de)com- || +|| press a 2- to 4-dimensional IEEE 754 floating point array. For further infor- || +|| mation use the --help (-h) argument in the command-line or consult the appro- || +|| priate README file. || +|| || +|| STRUCTS: || +|| -------- || +|| DESCRIPTION NEEDED. || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description || +|| ---- ------ --------- ------- ----------- || +|| 13.10.2017 Patrick Vogler B87D120 V 0.1.0 source file created || +|| 26.11.2020 Patrick Vogler B87E7E4 V 0.1.0 Command line tool refac- || +|| tored. || +|| || +|| || +|| ------------------------------------------------------------------------------------------------------ || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted || +|| provided that the following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of || +|| conditions and the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list || +|| of conditions and the following disclaimer in the documentation and/or other materials || +|| provided with the distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED || +|| WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A || +|| PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR || +|| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT || +|| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS || +|| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR || +|| TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF || +|| ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*====================================================================================================================*/ +#ifndef BWC_CMDL_H +#define BWC_CMDL_H + + /********************************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \********************************************************************************************************************/ + #include + + /********************************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \********************************************************************************************************************/ + /*------------------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros define minimum and maximum operators as well as an operator used ! + ! to evaluate the size of an array. ! + ! ! + ! MACROS: ! + ! ------- ! + ! Name Description ! + ! ---- ----------- ! + ! MAX(x, y) - Returns the maximum value of ! + ! two values. ! + ! ! + ! MIN(x, y) - Returns the minimum value of ! + ! two values. ! + ! ! + ! GET_LEN(x) - Returns the size of an array. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description ! + ! ---- ------ --------- ------- ----------- ! + ! 21.03.2018 Patrick Vogler B87D120 V 0.1.0 macros created ! + ! 16.09.2019 Patrick Vogler B87E7E4 V 0.1.0 Added GET_LEN(X) macro. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + #define MAX(x, y) (((x) < (y))?(y):(x)) + #define MIN(x, y) (((x) > (y))?(y):(x)) + + /*------------------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These Constants define codestream markers used to create the embedded code- ! + ! stream. ! + ! ! + ! MACROS: ! + ! ------- ! + ! Name Description ! + ! ---- ----------- ! + ! SOC - Start of code-stream ! + ! SGI - Global data-set information ! + ! SGC - Global control parameters ! + ! SGR - Global register containing tile ! + ! bitstream size information ! + ! SAX - Auxiliary data-set information ! + ! TLM - Packet lengths: main header ! + ! PLM - Packet lengths: tile-part ! + ! PPM - Quantization default ! + ! COM - Comment ! + ! EOH - End of header ! + ! PLT - Packed packet headers: main header ! + ! PPT - Packed packet headers: tile-part ! + ! SOT - Start of tile ! + ! SOP - Start of packet ! + ! EPH - End of packet header ! + ! SOD - Start of data ! + ! EOC - End of code-stream ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description ! + ! ---- ------ --------- ------- ----------- ! + ! 01.12.2017 Patrick Vogler B87D120 V 0.1.0 macros created ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + #define SOC 0xFF50 + #define SGI 0xFF51 + #define SGC 0xFF52 + #define SAX 0xFF53 + #define TLM 0xFF54 + #define PLM 0xFF55 + #define PPM 0xFF56 + #define COM 0xFF57 + #define EOH 0xFF58 + #define PLT 0xFF60 + #define PPT 0xFF61 + #define SOT 0xFF90 + #define SOP 0xFF91 + #define EPH 0xFF92 + #define SOD 0xFF93 + #define EOC 0xFFFF + + /*------------------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros define flags used for codestream parsing. ! + ! ! + ! MACROS: ! + ! ------- ! + ! Name Description ! + ! ---- ----------- ! + ! CODESTREAM_OK - No errors detected in Codestream ! + ! ! + ! CODESTREAM_READ - Codestream has been fully read. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description ! + ! ---- ------ --------- ------- ----------- ! + ! 01.08.2019 Patrick Vogler B87D120 V 0.1.0 macros created ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + #define CODESTREAM_OK 0x00 + #define CODESTREAM_READ 0x80 + + /*------------------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These Constants define common error messages used throughout the bwc library. ! + ! ! + ! MACROS: ! + ! ------- ! + ! Name Description ! + ! ---- ----------- ! + ! CSTERROR - Codestream parser has encoun- ! + ! tered invalid marker. ! + ! ! + ! MEMERROR - Allocation has returned a NULL ! + ! pointer due to limited memory. ! + ! ! + ! RDERROR - Invalid number of bytes read ! + ! from file. ! + ! ! + ! WRTERROR - Invalid number of bytes writ- ! + ! ten to file. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description ! + ! ---- ------ --------- ------- ----------- ! + ! 01.12.2017 Patrick Vogler B87D120 V 0.1.0 macros created ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + #define CSTERROR "o##########################################################o\n"\ + "| ERROR: Invalid Codestream |\n"\ + "o##########################################################o\n" + + #define MEMERROR "o##########################################################o\n"\ + "| ERROR: Out of Memory |\n"\ + "o##########################################################o\n" + + #define RDERROR "o##########################################################o\n"\ + "| ERROR: Invalid Number of Bytes Read from File. |\n"\ + "o##########################################################o\n" + + #define WRTERROR "o##########################################################o\n"\ + "| ERROR: Invalid Number of Bytes Written to File. |\n"\ + "o##########################################################o\n" + + #define GET_DIM(x) (sizeof(x)/sizeof(*(x))) + /********************************************************************************************************************\ + || ___ ____ ____ ____ _ _ _ ____ ___ ___ _ _ ___ ____ ____ || + || | \ |___ |__/ |__/ | | | |___ | \ | \_/ |__] |___ [__ || + || |__/ |___ | \ | \ | \/ |___ |__/ | | | |___ ___] || + || || + \********************************************************************************************************************/ + /*------------------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This structure defines the attributes of a single argument supported by the bwc ! + ! command line tool. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Name Type Description ! + ! ---- ---- ----------- ! + ! active char - Flag indicating if the argu- ! + ! ment is active. ! + ! ! + ! arg_long char - Long form of the argument name. ! + ! ! + ! arg_short char - Short form of the argument ! + ! name. ! + ! ! + ! arg_type char - Flag signaling if the argument ! + ! is optional. ! + ! ! + ! type char - Flag signaling the argument ! + ! type. ! + ! ! + ! usage char - A string of 24 characters de- ! + ! scribing the argument usage. ! + ! ! + ! definition char - A string of 1024 characters ! + ! containing the argument de- ! + ! scription. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description ! + ! ---- ------ --------- ------- ----------- ! + ! 14.02.2019 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! 26.11.2020 Patrick Vogler B87E7E4 V 0.1.0 clean up ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + typedef struct + { + char active; + char arg_long[25]; + char arg_short[3]; + char arg_type[4]; + char type[5]; + char usage[25]; + char definition[1024]; + } bwc_cmdl_args; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! DESCRIPTION: ! + ! ------------ ! + ! This structure describes a linked list which stores all the arguments and their ! + ! attributes supplied to the command line tool by the user. ! + ! ! + ! PARAMETERS: ! + ! ----------- ! + ! Name Type Description ! + ! ---- ---- ----------- ! + ! hash unsigned int(64 bit) - Uniquely identifiable hash that ! + ! corresponds to the arg/opt name. ! + ! ! + ! count unsigned int(8 bit) - Counter that signifies the num- ! + ! ber of modifier values stored ! + ! in the linked list node. ! + ! ! + ! dim unsigned int(8 bit) - Dimension(s) for which the mod- ! + ! ifiers have been defined ! + ! ! + ! active char - Flag indicating if the arg/opt ! + ! is active. ! + ! ! + ! num_opt double* - Array of numerical modifier ! + ! values. ! + ! ! + ! lit_opt char** - Character array of literal mod- ! + ! ifier values. ! + ! ! + ! DEPENDENCIES: ! + ! ------------- ! + ! Name TYPE ! + ! ---- ---- ! + ! next opt* ! + ! ! + ! root opt* ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Change Id Release Description ! + ! ---- ------ --------- ------- ----------- ! + ! 26.04.2019 Patrick Vogler B87D120 V 0.1.0 struct created ! + ! 26.11.2020 Patrick Vogler B87E7E4 V 0.1.0 clean up ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + typedef struct arg + { + uint64_t hash; + uint8_t count; + uint8_t dim; + char active; + double *num_opt; + char **lit_opt; + struct arg *next; + struct arg *root; + } bwc_cmdl_arg_node; +#endif \ No newline at end of file diff --git a/public_header.py b/public_header.py new file mode 100644 index 0000000..489975e --- /dev/null +++ b/public_header.py @@ -0,0 +1,331 @@ +#*====================================================================================================================*# +#| |# +#| /$$$$$$$ /$$ /$$ /$$ /$$ |# +#| | $$__ $$|__/ | $$ /$ | $$| $$ |# +#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# +#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# +#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# +#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# +#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# +#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# +#| /$$ \ $$ | $$ |# +#| | $$$$$$/ | $$ |# +#| \______/ |__/ |# +#| |# +#| DESCRIPTION: |# +#| ------------ |# +#| This file describes python script used to assemble the public header file for the |# +#| BigWhoop compression library. |# +#| |# +#| DEVELOPMENT HISTORY: |# +#| -------------------- |# +#| |# +#| Date Author Change Id Release Description Of Change |# +#| ---- ------ --------- ------- --------------------- |# +#| 02.02.2020 Patrick Vogler B87D120 V 0.1.0 script created |# +#| |# +#| |# +#| ------------------------------------------------------------------------------------------------------ |# +#| |# +#| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart |# +#| |# +#| Redistribution and use in source and binary forms, with or without modification, are permitted |# +#| provided that the following conditions are met: |# +#| |# +#| (1) Redistributions of source code must retain the above copyright notice, this list of |# +#| conditions and the following disclaimer. |# +#| |# +#| (2) Redistributions in binary form must reproduce the above copyright notice, this list |# +#| of conditions and the following disclaimer in the documentation and/or other materials |# +#| provided with the distribution. |# +#| |# +#| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED |# +#| WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |# +#| PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR |# +#| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |# +#| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |# +#| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR |# +#| TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |# +#| ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |# +#| |# +#\====================================================================================================================/# +from argparse import ArgumentParser +from math import ceil, floor +from pathlib import Path + +import os +import re +import sys + +parser = ArgumentParser(description='Public Header Assembly Script') +parser.add_argument('-OMP', dest='OpenMP', action='store_const', + const=True, default=False, + help='OpenMP Parallelization') +parser.add_argument('-Single', dest='SinglePrecision', action='store_const', + const=True, default=False, + help='Compilation using Single Precision Encoder') + +args = parser.parse_args() + +current_path = Path().absolute() +source = current_path.joinpath('include/library/private') + +if os.path.isdir('include/library/public') == False: + os.mkdir('include/library/public') +destination = current_path.joinpath('include/library/public') + + + +with open(source.joinpath('libbwc.h')) as f: + regex = re.compile("(?<=Version )(?:(\d+\.(?:\d+\.)*\d+))") + Version = "" + tab = "" + + for line in f: + if not Version: + Version = regex.findall(line) + if("#include" in line): + tab = line[0:len(line) - len(line.lstrip(' '))] + if tab: + if not Version: + sys.exit("No Version was specified") + else: + break +f.close + +deliminator = tab + "/*" + (116 - len(tab)) * "=" + "*/\n" +ubox = tab + "/" + (118 - len(tab)) * "*" + "\\\n" +lbox = tab + "\\" + (118 - len(tab)) * "*" + "/\n" + +public_header = open(destination.joinpath('bwc.h'), 'w+') + + +public_header.write("/*====================================================================================================================*\\\n" + "|| ||\n" + "|| /$$$$$$$ /$$ /$$ /$$ /$$ ||\n" + "|| | $$__ $$|__/ | $$ /$ | $$| $$ ||\n" + "|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ ||\n" + "|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ ||\n" + "|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ ||\n" + "|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ ||\n" + "|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ ||\n" + "|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ ||\n" + "|| /$$ \ $$ | $$ ||\n" + "|| | $$$$$$/ | $$ ||\n" + "|| \______/ |__/ ||\n" + "|| ||\n" + "|| ||\n" + "|| Version " + + Version[-1] + " ||\n" + "|| ||\n" + "|| ------------------------------------------------------------------------------------------------------ ||\n" + "|| ||\n" + "|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart ||\n" + "|| ||\n" + "|| Redistribution and use in source and binary forms, with or without modification, are permitted provided ||\n" + "|| that the following conditions are met: ||\n" + "|| ||\n" + "|| (1) Redistributions of source code must retain the above copyright notice, this list of ||\n" + "|| conditions and the following disclaimer. ||\n" + "|| ||\n" + "|| (2) Redistributions in binary form must reproduce the above copyright notice, this list ||\n" + "|| of conditions and the following disclaimer in the documentation and/or other materials ||\n" + "|| provided with the distribution. ||\n" + "|| ||\n" + "|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED ||\n" + "|| WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ||\n" + "|| PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ||\n" + "|| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ||\n" + "|| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ||\n" + "|| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ||\n" + "|| TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ||\n" + "|| ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ||\n" + "|| ||\n" + "\*====================================================================================================================*/\n" + "#ifndef BWC_H\n" + "#define BWC_H\n") + +lspaces = ceil((116 - 31 - len(tab))/2) +rspaces = floor((116 - 31 - len(tab))/2) + +public_header.write(ubox + tab + "||" + lspaces * " " + "_ _ _ ____ _ _ _ ___ ____" + rspaces * " " + "||\n" + + tab + "||" + lspaces * " " + "| |\ | | | | | | \ |___" + rspaces * " " + "||\n" + + tab + "||" + lspaces * " " + "| | \| |___ |___ |__| |__/ |___" + rspaces * " " + "||\n" + + tab + "||" + (116 - len(tab)) * " " + "||\n" + lbox) + +public_header.write(tab + "#include \n" + tab + "#include \n\n") + +lspaces = ceil((116 - 62 - len(tab))/2) +rspaces = floor((116 - 62 - len(tab))/2) + +public_header.write(ubox + tab + "||" + lspaces * " " + "___ ____ _ _ _ _ ___ _ _ _ ____ ___ _ _ ___ ____ ____" + rspaces * " " + "||\n" + + tab + "||" + lspaces * " " + "|__] |__/ | |\/| | | | | | |___ | \_/ |__] |___ [__ " + rspaces * " " + "||\n" + + tab + "||" + lspaces * " " + "| | \ | | | | | | \/ |___ | | | |___ ___]" + rspaces * " " + "||\n" + + tab + "||" + (116 - len(tab)) * " " + "||\n" + lbox) + +if(args.SinglePrecision == True): + file = "prim_types_single.h" +else: + file = "prim_types_double.h" + +print_flag = 0 +with open(source.joinpath(file)) as f: + for line in f: + if("/*" in line and print_flag == 1): + break + if("typedef" in line or print_flag == 1): + print_flag = 1 + public_header.write(line) +f.close + +lspaces = ceil((116 - 29 - len(tab))/2) +rspaces = floor((116 - 29 - len(tab))/2) + +public_header.write(ubox + tab + "||" + lspaces * " " + "_ _ ____ ____ ____ ____ ____" + rspaces * " " + "||\n" + + tab + "||" + lspaces * " " + "|\/| |__| | |__/ | | [__ " + rspaces * " " + "||\n" + + tab + "||" + lspaces * " " + "| | | | |___ | \ |__| ___]" + rspaces * " " + "||\n" + + tab + "||" + (116 - len(tab)) * " " + "||\n" + lbox) + +with open(source.joinpath('prim_types_double.h')) as f: + for line in f: + if("#define" in line): + if("PREC_BIT" in line): + public_header.write(line) + elif("#define MAXIMUM_NO_PASSES" in line): + public_header.write(line + "\n") + break +f.close + +lspaces = ceil((116 - 42 - len(tab))/2) +rspaces = floor((116 - 42 - len(tab))/2) + +public_header.write(ubox + tab + "||" + lspaces * " " + "____ ____ _ _ ____ ___ ____ _ _ ___ ____" + rspaces * " " + "||\n" + + tab + "||" + lspaces * " " + "| | | |\ | [__ | |__| |\ | | [__ " + rspaces * " " + "||\n" + + tab + "||" + lspaces * " " + "|___ |__| | \| ___] | | | | \| | ___]" + rspaces * " " + "||\n" + + tab + "||" + (116 - len(tab)) * " " + "||\n" + lbox) + +print_flag = -1 +with open(source.joinpath('constants.h')) as f: + for line in f: + if(";" in line and print_flag == 1): + print_flag = 0 + public_header.write(line) + if("typedef" in line or print_flag == 1): + if(print_flag == 0): + public_header.write(deliminator) + print_flag = 1 + public_header.write(line) +f.close + +lspaces = ceil((116 - 64 - len(tab))/2) +rspaces = floor((116 - 64 - len(tab))/2) + +public_header.write("\n") +public_header.write(ubox + tab + "||" + lspaces * " " + "___ ____ ____ ____ _ _ _ ____ ___ ___ _ _ ___ ____ ____" + rspaces * " " + "||\n" + + tab + "||" + lspaces * " " + "| \ |___ |__/ |__/ | | | |___ | \ | \_/ |__] |___ [__ " + rspaces * " " + "||\n" + + tab + "||" + lspaces * " " + "|__/ |___ | \ | \ | \/ |___ |__/ | | | |___ ___]" + rspaces * " " + "||\n" + + tab + "||" + (116 - len(tab)) * " " + "||\n" + lbox) + +printFlg = False +delimFlg = False +preProcFlg = False +preProc = "" +buff = "" +brktCnt = 0 + +for file in ["mq_types.h", "types.h"]: + with open(source.joinpath(file)) as f: + for line in f: + if("typedef" in line): + while True: + if("#if" in line): + if("_OPENMP" in line): + preProcFlg = True + while True: + line = next(f) + if("endif" in line): + break + preProc = preProc + line[len(tab):len(line)] + + if(preProcFlg and args.OpenMP == True): + buff = buff + preProc + + preProcFlg = False + preProc = "" + else: + buff = buff + line + + if("{" in line): + brktCnt = brktCnt + 1 + + if("}" in line): + brktCnt = brktCnt - 1 + if(brktCnt == 0): + break + line = next(f) + + if("bwc_" in line): + if(printFlg == True): + buff = deliminator + buff + else: + printFlg = True + public_header.write(buff) + + buff = "" + f.close + +lspaces = ceil((116 - 70 - len(tab))/2) +rspaces = floor((116 - 70 - len(tab))/2) + +public_header.write("\n" + ubox + tab + "||" + lspaces * " " + "___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____" + rspaces * " " + "||\n" + + tab + "||" + lspaces * " " + "|__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ " + rspaces * " " + "||\n" + + tab + "||" + lspaces * " " + "| |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___]" + rspaces * " " + "||\n" + + tab + "||" + (116 - len(tab)) * " " + "||\n" + lbox) + +files = os.listdir("include/library/private") +printFlg = False +ltab = 0 +tmp = "" +buff = "" + +for file in files: + with open(source.joinpath(file)) as f: + for line in f: + + if("#ifdef" in line or "#if defined" in line): + if("_OPENMP" in line and args.OpenMP == True): + ltab = len(tab) + line = next(f) + else: + while ("#endif" not in line): + line = next(f) + if("#endif" in line): + ltab = 0 + + if("(" in line): + tmp = line[0:line.index('(')] + tmp = tmp[tmp.rfind(' '):-1] + else: + tmp = "" + if("bwc_" in tmp and "!" not in line): + if("/*" in buff or "*/" in buff): + buff = "" + else: + buff = buff[ltab:len(buff)] + + if(print_flag == True): + buff = deliminator + buff + else: + print_flag = True + + while True: + buff = buff + line[ltab:len(line)] + if(");" in line): + break + line = next(f) + + public_header.write(buff) + buff = line + f.close +public_header.write("#endif") +public_header.close \ No newline at end of file diff --git a/src/interfaces/python/bwc.py b/src/interfaces/python/bwc.py new file mode 100644 index 0000000..474dc87 --- /dev/null +++ b/src/interfaces/python/bwc.py @@ -0,0 +1,221 @@ +#/=====================================================================================================================\# +#| |# +#| /$$$$$$$ /$$ /$$ /$$ /$$ |# +#| | $$__ $$|__/ | $$ /$ | $$| $$ |# +#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# +#! | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# +#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# +#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# +#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# +#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# +#| /$$ \ $$ | $$ |# +#| | $$$$$$/ | $$ |# +#| \______/ |__/ |# +#| |# +#| DESCRIPTION: |# +#| ------------ |# +#| |# +#| This file defines a Python interface for the Big Whoop compression library |# +#| |# +#| FUNCTIONS: |# +#| ---------- |# +#| - bwc_free_field |# +#| - bwc_add_param |# +#| - bwc_set_tiles |# +#| - bwc_set_kernels |# +#| - bwc_set_decomp |# +#| - bwc_set_precincts |# +#| - bwc_set_codeblocks |# +#| - bwc_set_progression |# +#| - bwc_set_error_resilience |# +#| - bwc_set_quantization_style |# +#| - bwc_set_qm |# +#| - bwc_set_quantization_step_size |# +#| - bwc_set_nThreads |# +#| - bwc_set_memory_limit |# +#| - bwc_compress |# +#| - bwc_decompress |# +#| |# +#| |# +#| DEVELOPMENT HISTORY: |# +#| -------------------- |# +#| |# +#| Date Author Change Id Release Description |# +#| ---- ------ --------- ------- ----------- |# +#| 17.03.2021 Patrick Vogler B87D120 V 0.1.0 Python Module created |# +#| |# +#| |# +#| ------------------------------------------------------------------------------------------------------ |# +#| |# +#| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart |# +#| |# +#| Redistribution and use in source and binary forms, with or without modification, are permitted |# +#| provided that the following conditions are met: |# +#| |# +#| (1) Redistributions of source code must retain the above copyright notice, this list of |# +#| conditions and the following disclaimer. |# +#| |# +#| (2) Redistributions in binary form must reproduce the above copyright notice, this list |# +#| of conditions and the following disclaimer in the documentation and/or other materials |# +#| provided with the distribution. |# +#| |# +#| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED |# +#| WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |# +#| PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR |# +#| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |# +#| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |# +#| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR |# +#| TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |# +#| ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |# +#| |# +#\=====================================================================================================================/# +#/=====================================================================================================================\# +#| _ _ _ ____ _ _ _ ___ ____ |# +#| | |\ | | | | | | \ |___ |# +#| | | \| |___ |___ |__| |__/ |___ |# +#| |# +#\=====================================================================================================================/# +import ctypes + +from numpy.ctypeslib import ndpointer +from enum import Enum + +libbwc = ctypes.cdll.LoadLibrary("../../../lib/libbwc.so") + +#/=====================================================================================================================\# +#| ____ ____ _ _ ____ ___ ____ _ _ ___ ____ |# +#| | | | |\ | [__ | |__| |\ | | [__ |# +#| |___ |__| | \| ___] | | | | \| | ___] |# +#| |# +#\=====================================================================================================================/# +class _const(): + class DWT(Enum): + CDF_9_7 = 0 + LEGALL_5_3 = 1 + HAAR = 2 + + class PROG(Enum): + LRCP = 0 + + class QT(object): + NONE = 0 + DERIVED = 1 + + class TILE(Enum): + SIZEOF = 0 + NUMBOF = 1 +const = _const() + +#/=====================================================================================================================\# +#| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ |# +#| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ |# +#| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] |# +#| |# +#\=====================================================================================================================/# +def free_data(data): + fun = libbwc.bwc_free_data + fun.restype = None + fun.argtypes = [ctypes.c_void_p] + fun(data) +#=======================================================================================================================# +def initialize_data(data, nX, nY, nZ, nTS, nPar, file_extension): + fun = libbwc.bwc_initialize_data + fun.restype = ctypes.c_void_p + fun.argtypes = [ndpointer(ctypes.c_double, flags="C_CONTIGUOUS"), + ctypes.c_uint64, + ctypes.c_uint64, + ctypes.c_uint64, + ctypes.c_uint16, + ctypes.c_uint8, + ctypes.c_char_p] + return ctypes.c_void_p(fun(data, nX, nY, nZ, nTS, nPar, file_extension.encode('utf-8'))) +#=======================================================================================================================# +def get_data(data, buffer, size): + fun = libbwc.bwc_get_data + fun.restype = None + fun.argtypes = [ctypes.c_void_p, + ndpointer(ctypes.c_double, flags="C_CONTIGUOUS"), + ctypes.c_uint64] + fun(data, buffer, size) +#=======================================================================================================================# +def add_param(data, name, sample, dim, precision): + fun = libbwc.bwc_add_param + fun.restype = None + fun.argtypes = [ctypes.c_void_p, + ctypes.c_char_p, + ctypes.c_uint16, + ctypes.c_uint8, + ctypes.c_uint8] + fun(data, name.encode('utf-8'), sample, dim, precision) +#=======================================================================================================================# +def kill_compression(field): + fun = libbwc.bwc_kill_compression + fun.restype = None + fun.argtypes = [ctypes.c_void_p] + fun(field) +#=======================================================================================================================# +def initialize_field(data): + fun = libbwc.bwc_initialize_field + fun.restype = ctypes.c_void_p + fun.argtypes = [ctypes.c_void_p] + return ctypes.c_void_p(fun(data)) +#=======================================================================================================================# +def set_nThreads(field, nThreads): + fun = libbwc.bwc_set_nThreads + fun.restype = None + fun.argtypes = [ctypes.c_void_p, ctypes.c_int8] + fun(field, nThreads) +#=======================================================================================================================# +def set_codeblocks(field, cbX, cbY, cbZ, cbTS): + fun = libbwc.bwc_set_codeblocks + fun.restype = None + fun.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint8, ctypes.c_uint8, ctypes.c_uint8] + fun(field, cbX, cbY, cbZ, cbTS) +#=======================================================================================================================# +def set_decomp(field, decompX, decompY, decompZ, decompTS): + fun = libbwc.bwc_set_decomp + fun.restype = None + fun.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint8, ctypes.c_uint8, ctypes.c_uint8] + fun(field, decompX, decompY, decompZ, decompTS) +#=======================================================================================================================# +def set_qm(field, Qm): + fun = libbwc.bwc_set_qm + fun.restype = None + fun.argtypes = [ctypes.c_void_p, ctypes.c_int8] + fun(field, Qm) +#=======================================================================================================================# +def set_tiles(field, tilesX, tilesY, tilesZ, tilesTS, instr): + fun = libbwc.bwc_set_tiles + fun.restype = None + fun.argtypes = [ctypes.c_void_p, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_char_p] + fun(field, tilesX, tilesY, tilesZ, tilesTS, instr.encode('utf-8')) +#=======================================================================================================================# +def set_precincts(field, pX, pY, pZ, pTS): + fun = libbwc.bwc_set_precincts + fun.restype = None + fun.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint8, ctypes.c_uint8, ctypes.c_uint8] + fun(field, pX, pY, pZ, pTS) +#=======================================================================================================================# +def create_compression(field, rate_control): + fun = libbwc.bwc_create_compression + fun.restype = None + fun.argtypes = [ctypes.c_void_p, ctypes.c_char_p] + fun(field, rate_control.encode('utf-8')) +#=======================================================================================================================# +def compress(field, data): + fun = libbwc.bwc_compress + fun.restype = None + fun.argtypes = [ctypes.c_void_p, ctypes.c_void_p] + fun(field, data) +#=======================================================================================================================# +def create_decompression(field, data): + fun = libbwc.bwc_create_decompression + fun.restype = ctypes.c_void_p + fun.argtypes = [ctypes.c_void_p, ctypes.c_uint8] + return ctypes.c_void_p(fun(field, data)) +#=======================================================================================================================# +def decompress(field, data): + fun = libbwc.bwc_decompress + fun.restype = None + fun.argtypes = [ctypes.c_void_p, ctypes.c_void_p] + fun(field, data) \ No newline at end of file diff --git a/src/interfaces/reader/eas3.c b/src/interfaces/reader/eas3.c new file mode 100644 index 0000000..5a6a6cf --- /dev/null +++ b/src/interfaces/reader/eas3.c @@ -0,0 +1,1127 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| FILE NAME: eas3.c || +|| || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This file defines simple read and write functions used to access conforming eas3 datasets. || +|| || +|| FILE REFERENCES: || +|| ---------------- || +|| || +|| Name I/O Description || +|| ---- --- ----------- || +|| fp input/output - Numerical dataset stored in the EAS3 data format. || +|| || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| - read_eas3 || +|| - write_eas3 || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 20.6.2018 Patrick Vogler B87D120 V 0.1.0 source file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ + +/************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\************************************************************************************************************/ +#include +#include +#include +#include +#include + +#include "eas3.h" +#include "bwccmdl.h" + +/************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function converts the endianess of half, single or double precision values. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! value void* - Memory address of the parame- ! +! ter to be converted. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 30.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 21.11.2019 Patrick Vogler B87E7E4 V 0.1.0 functionality expanded ! +! to 32 bit integers ! +! 21.11.2019 Patrick Vogler B87E7E4 V 0.1.0 functionality expanded ! +! to 16 bit integers ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +endian_conversion(void *value, + uint8_t const accuracy) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(value); + + switch(accuracy) + { + case 2: + { + uint16_t *tmp = (uint16_t*)value; + + *tmp = (uint16_t)( *tmp << 8) | + (uint16_t)( *tmp >> 8); + break; + } + + case 4: + { + uint32_t *tmp = (uint32_t*)value; + + *tmp = (uint32_t)((*tmp << 8) & 0xFF00FF00) | + (uint32_t)((*tmp >> 8) & 0x00FF00FF); + + *tmp = (uint32_t)( *tmp << 16) | + (uint32_t)( *tmp >> 16); + break; + } + + case 8: + { + uint64_t *tmp = (uint64_t*)value; + + *tmp = (uint64_t)((*tmp << 8) & 0xFF00FF00FF00FF00ULL) | + (uint64_t)((*tmp >> 8) & 0x00FF00FF00FF00FFULL); + + *tmp = (uint64_t)((*tmp << 16) & 0xFFFF0000FFFF0000ULL) | + (uint64_t)((*tmp >> 16) & 0x0000FFFF0000FFFFULL); + + *tmp = (uint64_t)( *tmp << 32) | + (uint64_t)( *tmp >> 32); + break; + } + default: + { + break; + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar read_eas3_header(bwc_data *const data) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function opens an eas3 file and checks it for its validity. Once the specified file ! +! has been verified, its header and flow field data is read and stored in the bwc_data ! +! structure. ! +! ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! filename char* - Defines the filename of the eas3 file ! +! that is to be opened and read. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! file - Defines a structure used to store all ! +! the relevant parameters and the data ! +! field of an eas3 file. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uchar +read_eas3_header(bwc_data *const data) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 Lread; + uint64 i; + uint8 precision; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar *buffer_char; + char param_name[ATTRLEN + 1] = {}; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_inf *info; + bwc_stream *aux; + eas3_std_params params; + + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(data); + + /*--------------------------------------------------------*\ + ! Save the file pointer and data info structure in tempo- ! + ! rary variables to make the code more readable. ! + \*--------------------------------------------------------*/ + fp = data->file.fp; + info = &data->info; + + /*--------------------------------------------------------*\ + ! Allocate the character buffer used to store chunks of ! + ! memory read from the specified file. ! + \*--------------------------------------------------------*/ + buffer_char = calloc(20, sizeof(uchar)); + if(!buffer_char) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Read the first 20 bits of the specified file that store ! + ! the identifier of an eas3 file. ! + \*--------------------------------------------------------*/ + if(fread(buffer_char, sizeof(uchar) , 20, fp) != 20) + { + // invalid read + fprintf(stderr, RDERROR); + free(buffer_char); + return 1; + } + + /*--------------------------------------------------------*\ + ! Check if the identifier corresponds to a valid EAS3 file.! + ! If this is not the case, close the file pointer and exit ! + ! the bwc command-line tool. ! + \*--------------------------------------------------------*/ + if(!strstr((char*)buffer_char, "EAS3_I8R8")) + { + // invalid file type + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Invalid EAS3 file format |\n"\ + "o##########################################################o\n"); + free(buffer_char); + return 1; + } + + /*--------------------------------------------------------*\ + ! Allocate the auxiliary information packed stream. ! + \*--------------------------------------------------------*/ + data->codestream.aux = calloc(1, sizeof(bwc_packed_stream)); + if(!data->codestream.aux) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(buffer_char); + return 1; + } + + /*--------------------------------------------------------*\ + ! Initialize the stream for the auxiliary information mem- ! + ! ory block. The initial size of the auxiliary memory ! + ! block has been chosen arbitrarily and should be large ! + ! enough to prevent excessive reallocation. ! + \*--------------------------------------------------------*/ + aux = bwc_init_stream(NULL, AUX_SIZE, 'c'); + if(!aux) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(buffer_char); + return 1; + } + + /*--------------------------------------------------------*\ + ! Read the next 22 bytes from the specified file that re- ! + ! present the eas3 standard parameters. The information ! + ! is stored in the eas3_std_params structure. ! + \*--------------------------------------------------------*/ + if(fread(¶ms, sizeof(uint64), 22, fp) != 22) + { + // invalid read + fprintf(stderr, RDERROR); + free(buffer_char); + return 1; + } + + /*--------------------------------------------------------*\ + ! Check if the specified file is of the EAS3 type. ! + \*--------------------------------------------------------*/ + if(params.file_type == EAS2_TYPE) + { + // invalid file format + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: The EAS2 file format is not supported |\n"\ + "o##########################################################o\n"); + free(buffer_char); + return 1; + } + + /*--------------------------------------------------------*\ + ! Emit a file format hash to the aux stream to identify it ! + ! as a eas3 auxiliary information block. This hash can be ! + ! used to properly handle decompression into an eas3 file ! + ! or conversion to other file formats. ! + \*--------------------------------------------------------*/ + // emit_symbol(aux, hash("eas3"), 8); + + /*--------------------------------------------------------*\ + ! Emit the standard parameters to the auxiliary informa- ! + ! tion information memory block. ! + \*--------------------------------------------------------*/ + bwc_emit_chunck(aux, (uchar*)¶ms, 176); + + /*--------------------------------------------------------*\ + ! Convert the parameters required for the bwc compression ! + ! stage to little endian and store them in the file info ! + ! structure. ! + \*--------------------------------------------------------*/ + endian_conversion(¶ms.nzs, 8); + info->nTS = (uint16)params.nzs; + + endian_conversion(¶ms.npar, 8); + info->nPar = (uint8)params.npar; + + endian_conversion(¶ms.ndim1, 8); + info->nX = (uint64)params.ndim1; + + endian_conversion(¶ms.ndim2, 8); + info->nY = (uint64)params.ndim2; + + endian_conversion(¶ms.ndim3, 8); + info->nZ = (uint64)params.ndim3; + + endian_conversion(¶ms.accuracy, 8); + if(params.accuracy == 1) + { + precision = 4; + } + else if(params.accuracy == 2) + { + precision = 8; + } + else + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: The accuracy of the specified dataset is not sup- |\n"\ + "| ported by the compression algorithm. |\n"\ + "o##########################################################o\n"); + return 1; + } + + /*--------------------------------------------------------*\ + ! Convert the size parameters, used to load the rest of the! + ! header, to little endian. ! + \*--------------------------------------------------------*/ + endian_conversion(¶ms.size_time, 8); + endian_conversion(¶ms.size_parameter, 8); + endian_conversion(¶ms.size_dim1, 8); + endian_conversion(¶ms.size_dim2, 8); + endian_conversion(¶ms.size_dim3, 8); + endian_conversion(¶ms.udef_char_size, 8); + endian_conversion(¶ms.udef_int_size, 8); + endian_conversion(¶ms.udef_real_size, 8); + + /*--------------------------------------------------------*\ + ! Allocate the time step array. If successful, read the ! + ! timesteps from the file stream. ! + \*--------------------------------------------------------*/ + buffer_char = realloc(buffer_char, info->nTS * sizeof(uint64)); + if(!buffer_char) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + if(fread(buffer_char, sizeof(uint64), info->nTS, fp) != info->nTS) + { + // invalid read + fprintf(stderr, RDERROR); + free(buffer_char); + return 1; + } + + /*--------------------------------------------------------*\ + ! Emit the time step array to the auxiliary information ! + ! memory block. ! + \*--------------------------------------------------------*/ + bwc_emit_chunck(aux, buffer_char, info->nTS * sizeof(uint64)); + + /*--------------------------------------------------------*\ + ! Check if any attributes have been specified in the eas3 ! + ! file. ! + \*--------------------------------------------------------*/ + if(params.attribute_mode == EAS3_ALL_ATTR) + { + /*--------------------------------------------------------*\ + ! Allocate the buffer character array. If successful, read ! + ! the timestep attributes from the file stream. ! + \*--------------------------------------------------------*/ + buffer_char = realloc(buffer_char, info->nTS * ATTRLEN * sizeof(char)); + if(!buffer_char) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(buffer_char); + return 1; + } + + if(fread(buffer_char, sizeof(char), info->nTS * ATTRLEN, fp) != (info->nTS * ATTRLEN)) + { + // invalid read + fprintf(stderr, RDERROR); + free(buffer_char); + return 1; + } + + /*--------------------------------------------------------*\ + ! Emit the timestep attribute array to the auxiliary infor-! + ! mation memory block. ! + \*--------------------------------------------------------*/ + bwc_emit_chunck(aux, buffer_char, info->nTS * ATTRLEN * sizeof(char)); + + for(i = 0; i < info->nPar; ++i) + { + /*--------------------------------------------------------*\ + ! Read the parameter name from the file stream and add all ! + ! the necessary parameter information to the paramter ! + ! linked list. ! + \*--------------------------------------------------------*/ + if(fread(param_name, sizeof(char), ATTRLEN, fp) != ATTRLEN) + { + // invalid read + fprintf(stderr, RDERROR); + free(buffer_char); + return 1; + } + + bwc_add_param(data, param_name, 0, (DIM_X | DIM_Y | DIM_Z), precision); + + /*--------------------------------------------------------*\ + ! Read the parameter name from the file stream and add all ! + ! the necessary parameter information to the paramter ! + ! linked list. | + \*--------------------------------------------------------*/ + memset(param_name, 0, ATTRLEN + 1); + } + } + + /*--------------------------------------------------------*\ + ! Evaluate the number of bytes that remain to be read from ! + ! the eas3 file header. ! + \*--------------------------------------------------------*/ + Lread = 0; + Lread += (params.attribute_mode == EAS3_ALL_ATTR) ? 3 * ATTRLEN : 0; + Lread += (params.gmode_time > EAS3_NO_G) ? params.size_time * sizeof(uint64) : 0; + Lread += (params.gmode_param > EAS3_NO_G) ? params.size_parameter * sizeof(uint64) : 0; + Lread += (params.gmode_dim1 > EAS3_NO_G) ? params.size_dim1 * sizeof(uint64) : 0; + Lread += (params.gmode_dim2 > EAS3_NO_G) ? params.size_dim2 * sizeof(uint64) : 0; + Lread += (params.gmode_dim3 > EAS3_NO_G) ? params.size_dim3 * sizeof(uint64) : 0; + Lread += (params.udef_param == EAS3_ALL_UDEF) ? params.udef_char_size * sizeof(char) * UDEFLEN + + params.udef_int_size * sizeof(uint64) + + params.udef_real_size * sizeof(double) : 0; + + /*--------------------------------------------------------*\ + ! Reallocate the buffer character array to allow for the ! + ! storage of the remaining header bytes of the eas3 file. ! + \*--------------------------------------------------------*/ + buffer_char = realloc(buffer_char, Lread * sizeof(uchar)); + if(!buffer_char) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(buffer_char); + return 1; + } + + /*--------------------------------------------------------*\ + ! Read the remaining header bytes from the file stream. ! + \*--------------------------------------------------------*/ + if(fread(buffer_char, sizeof(uchar), Lread, fp) != Lread) + { + // invalid read + fprintf(stderr, RDERROR); + free(buffer_char); + return 1; + } + + /*--------------------------------------------------------*\ + ! Emit the remaining header information the the auxiliary ! + ! information stream. ! + \*--------------------------------------------------------*/ + bwc_emit_chunck(aux, buffer_char, Lread); + + /*--------------------------------------------------------*\ + ! Free the buffer character array. ! + \*--------------------------------------------------------*/ + free(buffer_char); + + /*--------------------------------------------------------*\ + ! Terminate the auxiliary information stream. If success- ! + ! ful, the address to the aux memory block stored is ! + ! stored in the file structure alongside its size. ! + \*--------------------------------------------------------*/ + if(bwc_terminate_stream(aux, data->codestream.aux)) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar read_eas3_header(bwc_data *const data) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function opens an eas3 file and checks it for its validity. Once the specified file ! +! has been verified, its header and flow field data is read and stored in the bwc_data ! +! structure. ! +! ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! filename char* - Defines the filename of the eas3 file ! +! that is to be opened and read. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! file - Defines a structure used to store all ! +! the relevant parameters and the data ! +! field of an eas3 file. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uchar +write_eas3_header(bwc_data *const data) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 Lwrite; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar *buffer_char; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_inf *info; + bwc_stream *aux; + eas3_std_params *params; + bwc_cmd_opts_ll *param; + + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(data); + + /*--------------------------------------------------------*\ + ! Save the file pointer and data info structure in tempo- ! + ! rary variables to make the code more readable. ! + \*--------------------------------------------------------*/ + fp = data->file.fp; + info = &data->info; + + /*--------------------------------------------------------*\ + ! Write the valid EAS3 identifier to the specified file. ! + \*--------------------------------------------------------*/ + if(fwrite("EAS3_I8R8 ", sizeof(char), 20, fp) != 20) + { + // invalid read + fprintf(stderr, WRTERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Initialize the auxiliary information stream. ! + \*--------------------------------------------------------*/ + aux = bwc_init_stream(data->codestream.aux->memory, + data->codestream.aux->size, 'd'); + + /*--------------------------------------------------------*\ + ! Get the standard parameters from the auxiliary informa- ! + ! memory block and write them to the file stream. ! + \*--------------------------------------------------------*/ + params = (eas3_std_params*)bwc_get_chunck(aux, 176); + + if(fwrite(params, sizeof(uint64), 22, fp) != 22) + { + // invalid read + fprintf(stderr, WRTERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Convert the size parameters, used to write the rest of ! + ! the header, to little endian. ! + \*--------------------------------------------------------*/ + endian_conversion(¶ms->accuracy, 8); + endian_conversion(¶ms->size_time, 8); + endian_conversion(¶ms->size_parameter, 8); + endian_conversion(¶ms->size_dim1, 8); + endian_conversion(¶ms->size_dim2, 8); + endian_conversion(¶ms->size_dim3, 8); + endian_conversion(¶ms->udef_char_size, 8); + endian_conversion(¶ms->udef_int_size, 8); + endian_conversion(¶ms->udef_real_size, 8); + + /*--------------------------------------------------------*\ + ! Allocate the buffer character array. If successful, get ! + ! the timestep array from the auxiliary information block ! + ! and write it to the file stream. ! + \*--------------------------------------------------------*/ + buffer_char = bwc_get_chunck(aux, info->nTS * sizeof(uint64)); + if(!buffer_char) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(buffer_char); + return 1; + } + + if(fwrite(buffer_char, sizeof(uint64), info->nTS, fp) != info->nTS) + { + // invalid read + fprintf(stderr, WRTERROR); + free(buffer_char); + return 1; + } + free(buffer_char); + + /*--------------------------------------------------------*\ + ! Check if any attributes have been specified in the aux- ! + ! iliary information block. ! + \*--------------------------------------------------------*/ + if(params->attribute_mode == EAS3_ALL_ATTR) + { + /*--------------------------------------------------------*\ + ! Allocate the buffer character array. If successful, get ! + ! the timestep attribute array from the auxiliary informa- ! + ! tion block and write it to the file stream. ! + \*--------------------------------------------------------*/ + buffer_char = bwc_get_chunck(aux, info->nTS * ATTRLEN); + if(!buffer_char) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(buffer_char); + return 1; + } + + if(fwrite(buffer_char, sizeof(uchar), info->nTS * ATTRLEN, fp) != (info->nTS * ATTRLEN)) + { + // invalid read + fprintf(stderr, WRTERROR); + free(buffer_char); + return 1; + } + free(buffer_char); + + /*--------------------------------------------------------*\ + ! Loop through the parameter array and... ! + \*--------------------------------------------------------*/ + if(data->info.parameter) + { + param = data->info.parameter->root; + + while(param != NULL) + { + /*--------------------------------------------------------*\ + ! ... write the parameter name from the info structure to ! + ! the file stream. ! + \*--------------------------------------------------------*/ + if(fwrite(param->name, sizeof(char), ATTRLEN, fp) != ATTRLEN) + { + // invalid read + fprintf(stderr, WRTERROR); + free(buffer_char); + return 1; + } + + param = param -> next; + } + } + } + + /*--------------------------------------------------------*\ + ! Evaluate the number of bytes that remain to be read from ! + ! the auxiliary information block. ! + \*--------------------------------------------------------*/ + Lwrite = 0; + Lwrite += (params->attribute_mode == EAS3_ALL_ATTR) ? 3 * ATTRLEN : 0; + Lwrite += (params->gmode_time > EAS3_NO_G) ? params->size_time * sizeof(uint64) : 0; + Lwrite += (params->gmode_param > EAS3_NO_G) ? params->size_parameter * sizeof(uint64) : 0; + Lwrite += (params->gmode_dim1 > EAS3_NO_G) ? params->size_dim1 * sizeof(uint64) : 0; + Lwrite += (params->gmode_dim2 > EAS3_NO_G) ? params->size_dim2 * sizeof(uint64) : 0; + Lwrite += (params->gmode_dim3 > EAS3_NO_G) ? params->size_dim3 * sizeof(uint64) : 0; + Lwrite += (params->udef_param == EAS3_ALL_UDEF) ? params->udef_char_size * sizeof(char) * UDEFLEN + + params->udef_int_size * sizeof(uint64) + + params->udef_real_size * sizeof(double) : 0; + + /*--------------------------------------------------------*\ + ! Allocate the buffer character array. If successful, get ! + ! the remaining eas header bytes from the auxiliary infor- ! + ! mation block and write it to the file stream. ! + \*--------------------------------------------------------*/ + buffer_char = bwc_get_chunck(aux, Lwrite); + if(!buffer_char) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(buffer_char); + return 1; + } + + if(fwrite(buffer_char, sizeof(uchar), Lwrite, fp) != Lwrite) + { + // invalid read + fprintf(stderr, WRTERROR); + free(buffer_char); + return 1; + } + free(buffer_char); + + /*--------------------------------------------------------*\ + ! Free the auxiliary information memory block stream and ! + ! params structure. ! + \*--------------------------------------------------------*/ + free(aux); + free(params); + + return 0; +} + +/************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: bwc_data* read_eas3(const char* const filename) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function opens an eas3 file and checks it for its validity. Once the specified file ! +! has been verified, its header and flow field data is read and stored in the bwc_data ! +! structure. ! +! ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! filename char* - Defines the filename of the eas3 file ! +! that is to be opened and read. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! file - Defines a structure used to store all ! +! the relevant parameters and the data ! +! field of an eas3 file. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +bwc_data* +read_eas3(char *const filename) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 Lfield; + uint64 i; + uint32 root; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_data *data; + + /*--------------------------------------------------------*\ + ! Allocate the data structure. ! + \*--------------------------------------------------------*/ + data = calloc(1, sizeof(bwc_data)); + if(!data) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Set the file identifier used to select the appropriate ! + ! write operation during decompression. ! + \*--------------------------------------------------------*/ + strncpy(data->info.f_ext, "eas", 4); + + /*--------------------------------------------------------*\ + ! Open the specified file for reading. If the file doesn't ! + ! exist, exit the bwc command-line tool. ! + \*--------------------------------------------------------*/ + if((data->file.fp = fopen(filename, "rb")) == NULL) + { + // error opening file + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Could not open or read %-25s|\n"\ + "o##########################################################o\n", filename); + bwc_free_data(data); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Parse the eas3 header and store the information in the ! + ! data structure. ! + \*--------------------------------------------------------*/ + if(read_eas3_header(data)) + { + //error reading eas3 header + bwc_free_data(data); + } + + /*--------------------------------------------------------*\ + ! Determine the size of the dataset present in the eas3 ! + ! file and store the information in the bwc_gl_data struc- ! + ! ture. ! + \*--------------------------------------------------------*/ + root = ftell(data->file.fp); + fseek(data->file.fp, 0L, SEEK_END); + Lfield = (ftell(data->file.fp) - root) / sizeof(double); + fseek(data->file.fp, root, SEEK_SET); + + /*--------------------------------------------------------*\ + ! Check if the file_size coincide with the specified dimen-! + ! sions, timesteps number of parameters or bitdepth speci- ! + ! fied in the eas3 file header. ! + \*--------------------------------------------------------*/ + if(Lfield != data->info.nX * data->info.nY * + data->info.nZ * data->info.nTS * + data->info.nPar) + { + // error in file size + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Number of bytes present in the input file doesn't |\n"\ + "| coincide with the specified dimensions, timesteps |\n"\ + "| and number of parameters specified in the file |\n"\ + "| header. |\n"\ + "o##########################################################o\n"); + bwc_free_data(data); + return NULL; + } + + if(data->info.parameter->precision == 4) + { + /*--------------------------------------------------------*\ + ! Allocate the real field that will hold the numerical ! + ! dataset. ! + \*--------------------------------------------------------*/ + data->field.d = NULL; + data->field.f = calloc(Lfield, sizeof(float)); + if(!data->field.d) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(data); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Read the flow field data from the specified eas3 file. ! + \*--------------------------------------------------------*/ + if(fread(data->field.f, sizeof(float), Lfield, data->file.fp) != Lfield) + { + // invalid read + fprintf(stderr, RDERROR); + bwc_free_data(data); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Convert the flow field data read from the eas3 file from ! + ! big endian to little endian. ! + \*--------------------------------------------------------*/ + for(i = Lfield; i --> 0;) + { + endian_conversion(&data->field.f[i], 4); + } + } + else if(data->info.parameter->precision == 8) + { + /*--------------------------------------------------------*\ + ! Allocate the real field that will hold the numerical ! + ! dataset. ! + \*--------------------------------------------------------*/ + data->field.f = NULL; + data->field.d = calloc(Lfield, sizeof(double)); + if(!data->field.d) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(data); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Read the flow field data from the specified eas3 file. ! + \*--------------------------------------------------------*/ + if(fread(data->field.d, sizeof(double), Lfield, data->file.fp) != Lfield) + { + // invalid read + fprintf(stderr, RDERROR); + bwc_free_data(data); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Convert the flow field data read from the eas3 file from ! + ! big endian to little endian. ! + \*--------------------------------------------------------*/ + for(i = Lfield; i --> 0;) + { + endian_conversion(&data->field.d[i], 8); + } + } + + /*--------------------------------------------------------*\ + ! Close the file pointer and return the bwc_data structure ! + ! to the function caller. ! + \*--------------------------------------------------------*/ + fclose(data->file.fp); + data->file.fp = NULL; + return data; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar write_eas3(bwc_data *const file, char *const filename) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function creates a valid eas3 file from the information stored in the bwc_data ! +! structure. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! filename char* - Defines the filename of the eas3 file ! +! that is to be opened and read. ! +! ! +! file bwc_data* - Defines a structure used to store all ! +! the relevant parameters and the data ! +! field of an eas3 file. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +write_eas3(bwc_data *const data, char *const filename) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 Lfield; + uint64 i; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(data); + + /*--------------------------------------------------------*\ + ! Open the specified file for writing. If the file already ! + ! exist, discard its content. If the file cannot be creat- ! + ! ed, exit the bwc command-line tool. ! + \*--------------------------------------------------------*/ + if((data->file.fp = fopen(filename, "wb")) == NULL) + { + // error opening file + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Could not open or write %-24s|\n"\ + "o##########################################################o\n", filename); + return 1; + } + + /*--------------------------------------------------------*\ + ! Write the eas3 header to the specified file. ! + \*--------------------------------------------------------*/ + if(write_eas3_header(data)) + { + //error reading eas3 header + return 1; + } + + + /*--------------------------------------------------------*\ + ! Calculate the size of the data field used for the endian ! + ! conversion and write operations. ! + \*--------------------------------------------------------*/ + Lfield = data->info.nX * data->info.nY * + data->info.nZ * data->info.nTS * data->info.nPar; + + if(data->info.parameter->precision == 4) + { + /*--------------------------------------------------------*\ + ! Convert the flow field data from big endian to endian. ! + \*--------------------------------------------------------*/ + for(i = Lfield; i --> 0;) + { + endian_conversion(&data->field.f[i], 4); + } + + /*--------------------------------------------------------*\ + ! Write the flow field data to the specified eas3 file. ! + \*--------------------------------------------------------*/ + if(fwrite(data->field.f, sizeof(float), Lfield, data->file.fp) != Lfield) + { + // invalid read + fprintf(stderr, WRTERROR); + return 1; + } + } + else if(data->info.parameter->precision == 8) + { + /*--------------------------------------------------------*\ + ! Convert the flow field data from big endian to endian. ! + \*--------------------------------------------------------*/ + for(i = Lfield; i --> 0;) + { + endian_conversion(&data->field.d[i], 8); + } + + /*--------------------------------------------------------*\ + ! Write the flow field data to the specified eas3 file. ! + \*--------------------------------------------------------*/ + if(fwrite(data->field.d, sizeof(double), Lfield, data->file.fp) != Lfield) + { + // invalid read + fprintf(stderr, WRTERROR); + return 1; + } + } + + /*--------------------------------------------------------*\ + ! Close the file pointer and return to the function caller.! + \*--------------------------------------------------------*/ + fclose(data->file.fp); + data->file.fp = NULL; + return 0; +} \ No newline at end of file diff --git a/src/library/CMakeLists.txt b/src/library/CMakeLists.txt new file mode 100755 index 0000000..43ae796 --- /dev/null +++ b/src/library/CMakeLists.txt @@ -0,0 +1,126 @@ +#*====================================================================================================================*# +#| |# +#| /$$$$$$$ /$$ /$$ /$$ /$$ |# +#| | $$__ $$|__/ | $$ /$ | $$| $$ |# +#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# +#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# +#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# +#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# +#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# +#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# +#| /$$ \ $$ | $$ |# +#| | $$$$$$/ | $$ |# +#| \______/ |__/ |# +#| DESCRIPTION: |# +#| ------------ |# +#| Defines the cmake script for the libbwc library. |# +#| |# +#| |# +#| DEVELOPMENT HISTORY: |# +#| -------------------- |# +#| |# +#| Date Author Change Id Release Description Of Change |# +#| ---- ------ --------- ------- --------------------- |# +#| 30.08.2018 Patrick Vogler B87D120 V 0.1.0 cmake file created |# +#| 15.10.2021 Patrick Vogler B880CA2 V 0.1.1 Added install rules |# +#| |# +#| |# +#| ------------------------------------------------------------------------------------------------------ |# +#| |# +#| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart |# +#| |# +#| Redistribution and use in source and binary forms, with or without modification, are permitted |# +#| provided that the following conditions are met: |# +#| |# +#| (1) Redistributions of source code must retain the above copyright notice, this list of |# +#| conditions and the following disclaimer. |# +#| |# +#| (2) Redistributions in binary form must reproduce the above copyright notice, this list |# +#| of conditions and the following disclaimer in the documentation and/or other materials |# +#| provided with the distribution. |# +#| |# +#| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED |# +#| WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |# +#| PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR |# +#| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |# +#| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |# +#| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR |# +#| TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |# +#| ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |# +#| |# +#*====================================================================================================================*# +#*--------------------------------------------------------*# +# Assemble the public header for the BigWhoop library # +#*--------------------------------------------------------*# +set(PYTHON_ARGUMENT "") + +if("${CMAKE_BUILD_TYPE}" STREQUAL "Release") + if(OPENMP_FOUND) + set(PYTHON_ARGUMENT ${PYTHON_ARGUMENT} -OMP) + endif() +endif() + +if("${PREC}" STREQUAL "Single") + set(PYTHON_ARGUMENT ${PYTHON_ARGUMENT} -Single) +endif() + +execute_process(COMMAND python3 public_header.py ${PYTHON_ARGUMENT} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + +#*--------------------------------------------------------*# +# Set the linking type according to user choice and add # +# the library to the current project # +#*--------------------------------------------------------*# +if("${LINK}" STREQUAL "Static") + set(BWC_LINK "STATIC") +else() + set(BWC_LINK "SHARED") +endif() + +add_library(bwclib ${BWC_LINK} bitstream.c + libbwc.c + codestream.c + dwt.c + mq.c + tier1.c + tier2.c + tagtree.c) + +#*--------------------------------------------------------*# +# Set the target compile definition for the encoder/decod- # +# er bit precision. # +#*--------------------------------------------------------*# +if("${PREC}" STREQUAL "Single") + target_compile_definitions(bwclib PRIVATE -DBWC_SINGLE_PRECISION) +else() + target_compile_definitions(bwclib PRIVATE -DBWC_DOUBLE_PRECISION) +endif() + +#*--------------------------------------------------------*# +# Set the Version and SOVersion and define the public API # +# for the BigWhoop library. # +#*--------------------------------------------------------*# +set_target_properties(bwclib PROPERTIES VERSION ${BWC_VERSION} + SOVERSION ${BWC_VERSION_MAJOR} + PUBLIC_HEADER ${CMAKE_SOURCE_DIR}/include/library/public/bwc.h) + +#*--------------------------------------------------------*# +# Setup up the include directory for the BigWhoop library. # +#*--------------------------------------------------------*# +target_include_directories(bwclib PRIVATE ${CMAKE_SOURCE_DIR}/include/library/private) + +#*--------------------------------------------------------*# +# Link the BigWhoop library to the math.h library. # +#*--------------------------------------------------------*# +target_link_libraries(bwclib PRIVATE m) + +#*--------------------------------------------------------*# +# Setup the install directories. # +#*--------------------------------------------------------*# +install(FILES ${CMAKE_SOURCE_DIR}/include/library/public/bwc.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(TARGETS bwclib DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +#*--------------------------------------------------------*# +# Define the output name for the BigWhoop library. # +#*--------------------------------------------------------*# +set_property(TARGET bwclib PROPERTY OUTPUT_NAME bwc) \ No newline at end of file diff --git a/src/library/bitstream.c b/src/library/bitstream.c new file mode 100755 index 0000000..c38201d --- /dev/null +++ b/src/library/bitstream.c @@ -0,0 +1,1021 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| FILE NAME: bitstream.c || +|| || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This file describes a set of functions that can be used to create, manipulate and terminate || +|| a bitstream. These functions facilitate the creation or reading of a compressed bwc code- || +|| stream and can emit/extract information on a per bit, symbol (64-bit) or string basis. || +|| || +|| || +|| FILE REFERENCES: || +|| ---------------- || +|| || +|| Name I/O Description || +|| ---- --- ----------- || +|| none - - || +|| || +|| || +|| PRIVATE FUNCTIONS: || +|| ------------------ || +|| - || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| - bytes_used || +|| - bwc_init_stream || +|| - bwc_emit_chunck || +|| - bwc_emit_symbol || +|| - bwc_emit_bit || +|| - bwc_get_chunck || +|| - bwc_get_symbol || +|| - bwc_get_bit || +|| - bwc_terminate_stream || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 28.05.2018 Patrick Vogler B87D120 V 0.1.0 source file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ + +/************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\************************************************************************************************************/ +#include +#include +#include +#include + +#include "libbwc.h" + +/************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uint32 bytes_used(bwc_stream *const stream) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to evaluate the number of bytes that have already been ! +! written to the allocated bitstream memory block. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure that ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned int(32 bit) - Number of bites that have been written to the ! +! bitstream. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 13.05.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uint64 +bytes_used(bwc_stream *const stream) +{ + if(stream->T == 0xFF) + { + return stream->L + 1; + } + else + { + return stream->L; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: bwc_stream* bwc_init_stream(uchar* memory, uint32 size, char instr) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to initialize a bwc bitstream. For encoding, a null pointer ! +! is passed as a memory handle and the function will allocate a memory block with the ! +! specified stream size. For decoding, a valid memory handle, passed by the function ! +! caller, will be stored in the bwc_stream structure. The byte buffer counter t, ! +! stream size Lmax and size increment are initialized with their appropriate values. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! size unsigned int(32 bit) - Initial size of the bwc stream. ! +! ! +! memory unsigned char - Memory handle for the bwc stream memory ! +! block. ! +! ! +! instr char - Constant used to instruct the field ! +! initialization. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! bwc_stream* - Memory handle for the initialized bwc stream. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +bwc_stream* +bwc_init_stream(uchar* memory, uint32 size, char instr) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_stream *stream; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(instr == 'c' || instr == 'd'); + + /*--------------------------------------------------------*\ + ! Allocate the bwc stream structure. ! + \*--------------------------------------------------------*/ + stream = calloc(1, sizeof(bwc_stream)); + if(!stream) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Evaluate if a valid memory handle has been passed by the ! + ! function caller. ! + \*--------------------------------------------------------*/ + if(!memory) + { + /*--------------------------------------------------------*\ + ! If no valid memory handle has been passed, allocate a ! + ! memory block with the specifiec stream size. ! + \*--------------------------------------------------------*/ + stream->memory = calloc(size, sizeof(uchar)); + if(!stream->memory) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return NULL; + } + } + else + { + /*--------------------------------------------------------*\ + ! If a valid memory handle has been passed for decoding, ! + ! save the memory handle in the bwc stream structure. ! + \*--------------------------------------------------------*/ + stream->memory = memory; + } + + /*--------------------------------------------------------*\ + ! Initialize the byte buffer counter, stream size and size ! + ! increment for the current stream. ! + \*--------------------------------------------------------*/ + stream->t = (instr == 'c') ? 8 : 0; + stream->Lmax = size; + stream->size_incr = (uint64)(size / 2); + + /*--------------------------------------------------------*\ + ! Return the stream memory handle. ! + \*--------------------------------------------------------*/ + return stream; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_emit_chunck(bwc_stream *const stream, const uchar* string, const uint64 length) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to write an additional chunck of size length to a bwc bitstream. ! +! ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure used to assemble a bwc bit- ! +! bitstream. ! +! ! +! chunck unsigned char* - Memory handle for a data block that is ! +! to be written to the bwc bitstream. ! +! ! +! size unsigned int(64 bit) - Size of the data block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 22.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_emit_chunck(bwc_stream *const stream, const uchar* chunck, const uint64 size) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 Lreq; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + assert(chunck); + + /*--------------------------------------------------------*\ + ! Evaluate the memory block size if the current chunck of ! + ! data is written to the stream. ! + \*--------------------------------------------------------*/ + Lreq = (bytes_used(stream) + size); + + /*--------------------------------------------------------*\ + ! Check if the enough memory has been allocated for the ! + ! stream to store the additional data chunck. ! + \*--------------------------------------------------------*/ + if(Lreq > stream->Lmax) + { + /*--------------------------------------------------------*\ + ! If the stream is not large enough, check if this is due ! + ! to an error encountered in a previous writing operation ! + \*--------------------------------------------------------*/ + if(!stream->error) + { + /*--------------------------------------------------------*\ + ! If the error flag is not set, increase the stream size ! + ! until it is large enough to store the additional data ! + ! chunck. ! + \*--------------------------------------------------------*/ + while(Lreq > stream->Lmax) + { + stream->Lmax += stream->size_incr + size; + stream->size_incr = (uint64)(stream->Lmax / 2); + } + + /*--------------------------------------------------------*\ + ! Reallocate the stream data block. ! + \*--------------------------------------------------------*/ + stream->memory = realloc(stream->memory, stream->Lmax); + if(!stream->memory) + { + // memory allocation error + stream->error |= 1; + stream->Lmax = 0; + return; + } + } + else + { + /*--------------------------------------------------------*\ + ! Exit to function caller if error flag has been set. ! + \*--------------------------------------------------------*/ + return; + } + } + + /*--------------------------------------------------------*\ + ! Copy the additional data to the stream memory block. ! + \*--------------------------------------------------------*/ + memcpy(stream->memory + stream->L, chunck, size); + + /*--------------------------------------------------------*\ + ! Increment the number of bytes written to the stream with ! + ! the size of the newly added data chunck. ! + \*--------------------------------------------------------*/ + stream->L += size; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure used to assemble a bwc bit- ! +! bitstream. ! +! ! +! symbol unsigned int(64 bit) - Symbol that is to be written to the bwc ! +! bitstream. ! +! ! +! size unsigned int(8 bit) - Number of significant bytes in the ! +! symbol. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 22.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_emit_symbol(bwc_stream *const stream, const uint64 symbol, const uint8 size) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint8 byte; + int8 i; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + + /*--------------------------------------------------------*\ + ! Check if the enough memory has been allocated for the ! + ! stream to store the additional symbol. ! + \*--------------------------------------------------------*/ + if((bytes_used(stream) + size) > stream->Lmax) + { + /*--------------------------------------------------------*\ + ! If the stream is not large enough, check if this is due ! + ! to an error encountered in a previous writing operation ! + \*--------------------------------------------------------*/ + if(!stream->error) + { + /*--------------------------------------------------------*\ + ! If the error flag is not set, increment the stream size ! + ! to store the additional symbol. ! + \*--------------------------------------------------------*/ + stream->Lmax += stream->size_incr; + stream->size_incr = (uint64)(stream->Lmax / 2); + + /*--------------------------------------------------------*\ + ! Reallocate the stream data block. ! + \*--------------------------------------------------------*/ + stream->memory = realloc(stream->memory, stream->Lmax); + if(!stream->memory) + { + // memory allocation error + stream->error |= 1; + stream->Lmax = 0; + return; + } + } + else + { + /*--------------------------------------------------------*\ + ! Exit to function caller if error flag has been set. ! + \*--------------------------------------------------------*/ + return; + } + } + + /*--------------------------------------------------------*\ + ! Copy the additional symbol to the stream memory block ! + ! one byte at a time and Increment the number of bytes ! + ! written to the stream. ! + \*--------------------------------------------------------*/ + for(i = size; i --> 0;) + { + byte = (uint8)((symbol >> (8 * i)) & 0xFF); + stream->memory[stream->L++] = (uchar)byte; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_emit_bit(bwc_stream *const stream, const uint64 bit) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure used to assemble a bwc bit- ! +! bitstream. ! +! ! +! bit unsigned int(64 bit) - Bit that is to be written to the bwc ! +! bitstream. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 22.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_emit_bit(bwc_stream *const stream, const uint64 bit) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + + /*--------------------------------------------------------*\ + ! Decrement the bit buffer counter. ! + \*--------------------------------------------------------*/ + stream->t--; + + /*--------------------------------------------------------*\ + ! If the bit is significant, store the information at the ! + ! appropriate position in the bit buffer. ! + \*--------------------------------------------------------*/ + if(bit) + { + stream->T |= (1 << stream->t); + } + + /*--------------------------------------------------------*\ + ! Check the bit buffer counter to see if the bit buffer is ! + ! full. ! + \*--------------------------------------------------------*/ + if(!stream->t) + { + /*--------------------------------------------------------*\ + ! Check if the enough memory has been allocated for the ! + ! stream to store the additional byte. ! + \*--------------------------------------------------------*/ + if(bytes_used(stream) + 1 > stream->Lmax) + { + /*--------------------------------------------------------*\ + ! If the stream is not large enough, check if this is due ! + ! to an error encountered in a previous writing operation ! + \*--------------------------------------------------------*/ + if(!stream->error) + { + /*--------------------------------------------------------*\ + ! If the error flag is not set, increment the stream size ! + ! to store the additional byte. ! + \*--------------------------------------------------------*/ + stream->Lmax += stream->size_incr; + stream->size_incr = (uint64)(stream->Lmax / 2); + + /*--------------------------------------------------------*\ + ! Reallocate the stream data block. ! + \*--------------------------------------------------------*/ + stream->memory = realloc(stream->memory, stream->Lmax); + if(!stream->memory) + { + // memory allocation error + stream->error |= 1; + stream->Lmax = 0; + return; + } + } + else + { + /*--------------------------------------------------------*\ + ! Exit to function caller if error flag has been set. ! + \*--------------------------------------------------------*/ + return; + } + } + + /*--------------------------------------------------------*\ + ! Copy the additional byte to the stream memory block and ! + ! increment the number of bytes written to the stream. ! + \*--------------------------------------------------------*/ + stream->memory[stream->L++] = (uchar)stream->T; + + /*--------------------------------------------------------*\ + ! Reset the byte buffer counter. If the current buffer has ! + ! a value of 255, limit the counter to 7 bits to ensure ! + ! that the range FFFF to FF80 is reserved for the code- ! + ! stream markers. ! + \*--------------------------------------------------------*/ + if(stream->T == 0xFF) + { + stream->t = 7; + } + else + { + stream->t = 8; + } + + /*--------------------------------------------------------*\ + ! Reset the byte buffer. ! + \*--------------------------------------------------------*/ + stream->T = 0; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure used to assemble a bwc bit- ! +! bitstream. ! +! ! +! size unsigned int(64 bit) - Size of the data block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar* - Data chunck requested by the function caller. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 22.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar* +bwc_get_chunck(bwc_stream *const stream, const uint64 size) +{ + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar *tmp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + + /*--------------------------------------------------------*\ + ! Check if the number of bytes to be read from the stream ! + ! does not exceed the number of bytes still present in its ! + ! memory block. ! + \*--------------------------------------------------------*/ + if(bytes_used(stream) + size <= stream->Lmax) + { + /*--------------------------------------------------------*\ + ! Allocate a temporary array used to store the bytes that ! + ! are extracted from the stream. ! + \*--------------------------------------------------------*/ + tmp = calloc(size, sizeof(uchar)); + if(!tmp) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Copy the bytes requested from the function caller from ! + ! the stream to the temporary data block. ! + \*--------------------------------------------------------*/ + memcpy(tmp, stream->memory + stream->L, size); + + /*--------------------------------------------------------*\ + ! Increment the number of bytes read from the bitstream. ! + \*--------------------------------------------------------*/ + stream->L += size; + + /*--------------------------------------------------------*\ + ! Return the temporary data block to the function caller. ! + \*--------------------------------------------------------*/ + return tmp; + } + else + { + /*--------------------------------------------------------*\ + ! If the requested block size exceeds the information left ! + ! in the bitstream, set the bitstream error flag and ! + ! return a NULL pointer. ! + \*--------------------------------------------------------*/ + stream->error |= 1; + return NULL; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure used to assemble a bwc bit- ! +! bitstream. ! +! ! +! size unsigned int(8 bit) - Number of significant bytes in the ! +! symbol. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar* - Symbol requested by the function caller. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uint64 +bwc_get_symbol(bwc_stream *const stream, const uint8 size) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 symbol; + uint8 byte; + int8 i; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + + /*--------------------------------------------------------*\ + ! Check if the number of bytes to be read from the stream ! + ! does not exceed the number of bytes still present in its ! + ! memory block. ! + \*--------------------------------------------------------*/ + if(bytes_used(stream) + size <= stream->Lmax) + { + /*--------------------------------------------------------*\ + ! Extract the requested information from the bitstream one ! + ! byte at a time. Adjust the number of bytes read from the ! + ! stream accordingly. ! + \*--------------------------------------------------------*/ + for(i = size, symbol = 0; i --> 0;) + { + byte = (uint8)stream->memory[stream->L++]; + symbol |= ((uint64)byte << (i * 8)); + } + + /*--------------------------------------------------------*\ + ! Return the symbol to the function caller. ! + \*--------------------------------------------------------*/ + return symbol; + } + else + { + /*--------------------------------------------------------*\ + ! If the requested block size exceeds the information left ! + ! in the bitstream, set the bitstream error flag and ! + ! return zero. ! + \*--------------------------------------------------------*/ + stream->error |= 1; + return 0; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +bwc_get_bit(bwc_stream *const stream) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + + if(!stream->t) + { + if(stream->L == stream->Lmax) + { + return 1; + } + if(stream->T == 0xFF) + { + stream->t = 7; + } + else + { + stream->t = 8; + } + stream->T = (uint16)stream->memory[stream->L++]; + } + stream->t--; + return ((stream->T & (1 << stream->t)) >> stream->t); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +flush_stream(bwc_stream *const stream) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + + /*--------------------------------------------------------*\ + ! Check the if the bit buffer contains information. ! + \*--------------------------------------------------------*/ + if(stream->t != 8) + { + /*--------------------------------------------------------*\ + ! Check if the enough memory has been allocated for the ! + ! stream to store the additional byte. ! + \*--------------------------------------------------------*/ + if((bytes_used(stream) + 1) > stream->Lmax) + { + /*--------------------------------------------------------*\ + ! If the stream is not large enough, check if this is due ! + ! to an error encountered in a previous writing operation ! + \*--------------------------------------------------------*/ + if(!stream->error) + { + /*--------------------------------------------------------*\ + ! If the error flag is not set, increment the stream size ! + ! to store the additional byte. ! + \*--------------------------------------------------------*/ + stream->Lmax += stream->size_incr; + stream->size_incr = (uint64)(stream->Lmax / 2); + + /*--------------------------------------------------------*\ + ! Reallocate the stream data block. ! + \*--------------------------------------------------------*/ + stream->memory = realloc(stream->memory, stream->Lmax); + if(!stream->memory) + { + // memory allocation error + stream->error |= 1; + stream->Lmax = 0; + return; + } + } + else + { + /*--------------------------------------------------------*\ + ! Exit to function caller if error flag has been set. ! + \*--------------------------------------------------------*/ + return; + } + } + + /*--------------------------------------------------------*\ + ! Copy the additional byte to the stream memory block and ! + ! increment the number of bytes written to the stream. ! + \*--------------------------------------------------------*/ + stream->memory[stream->L++] = (uchar)stream->T; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +bwc_terminate_stream(bwc_stream *stream, bwc_packed_stream *const packed_stream) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + + if(packed_stream) + { + if(stream->error) + { + return 1; + } + else if(stream->L != stream->Lmax) + { + stream->Lmax = stream->L; + stream->memory = realloc(stream->memory, stream->Lmax); + if(!stream->memory) + { + // memory allocation error + fprintf(stderr, MEMERROR); + stream->Lmax = 0; + return 1; + } + } + + packed_stream->memory = stream->memory; + packed_stream->access = stream->memory; + packed_stream->size = stream->L; + packed_stream->position = 0; + } + else + { + free(stream->memory); + } + + free(stream); + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void release_packed_stream(bwc_packed_stream *stream) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to release all the information stored in a packed bitstream ! +! and reset the parameters for another (de)compression run. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_packed_stream - Packed bitstream used to store parts of ! +! the bwc codestream. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 22.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +release_packed_stream(bwc_packed_stream *stream) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + + /*--------------------------------------------------------*\ + ! Free the data block of the packed bitstream. ! + \*--------------------------------------------------------*/ + free(stream->memory); + + /*--------------------------------------------------------*\ + ! Reset all the packed stream parameters. ! + \*--------------------------------------------------------*/ + stream->access = NULL; + stream->position = 0; + stream->size = 0; +} \ No newline at end of file diff --git a/src/library/codestream.c b/src/library/codestream.c new file mode 100755 index 0000000..ab99f5e --- /dev/null +++ b/src/library/codestream.c @@ -0,0 +1,1824 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| FILE NAME: bitstream.c || +|| || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| FILE REFERENCES: || +|| ---------------- || +|| || +|| Name I/O Description || +|| ---- --- ----------- || +|| none - - || +|| || +|| || +|| PRIVATE FUNCTIONS: || +|| ------------------ || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 28.05.2018 Patrick Vogler B87D120 V 0.1.0 source file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ +/************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\************************************************************************************************************/ +#include +#include +#include +#include + +#include "libbwc.h" +#include "codestream.h" +#include "tier2.h" + +/************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! ! +! RETURN VALUE: ! +! ------------- ! +! - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uchar +can_read(bwc_stream *const stream, const uint64 length) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + assert(length); + + return (stream->L + length > stream->Lmax) ? 0 : 1; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void codestream_write_header(bwc_stream *const stream, bwc_field *const field) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is writes the main header, including the end of header (EOH) marker seg- ! +! ment to the bwc codestream. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! stream bwc_stream* - Structure used to assemble a bwc bit- ! +! bitstream. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 12.07.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +codestream_write_header(bwc_stream *const stream, bwc_field *const field) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint32 t; + uint16 Leoh; + uint8 p; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global as well as the subband control and info ! + ! structure to temporary variables to make the code more ! + ! readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = field->info; + + /*--------------------------------------------------------*\ + ! Calculate the size of the end of header (EOH) maker seg- ! + ! ment - excluding the EOH marker. ! + \*--------------------------------------------------------*/ + Leoh = 2 + (control->nTiles * info->nPar * 2 * PREC_BYTE); + + /*--------------------------------------------------------*\ + ! Emit the portion of the main header already created by ! + ! the bwc_create_compression function. ! + \*--------------------------------------------------------*/ + bwc_emit_chunck(stream, control->header.memory, control->header.size); + + /*--------------------------------------------------------*\ + ! Emit the end of header (EOH) marker and EOH marker seg- ! + ! ment size Leoh. ! + \*--------------------------------------------------------*/ + bwc_emit_symbol(stream, EOH, 2); + bwc_emit_symbol(stream, Leoh, 2); + + /*--------------------------------------------------------*\ + ! Loop through all tile parameters and... ! + \*--------------------------------------------------------*/ + for(t = 0; t < control->nTiles; ++t) + { + for(p = 0; p < info->nPar; ++p) + { + /*--------------------------------------------------------*\ + ! ...emit the maximum and minimum parameter value to the ! + ! header stream. ! + \*--------------------------------------------------------*/ + bwc_emit_symbol(stream, *(uint64 *)&field->tile[t].parameter[p].info.parameter_min, PREC_BYTE); + bwc_emit_symbol(stream, *(uint64 *)&field->tile[t].parameter[p].info.parameter_max, PREC_BYTE); + + /*--------------------------------------------------------*\ + ! Reset the maximum and minimum parameter value in the ! + ! parameter structure. ! + \*--------------------------------------------------------*/ + field->tile[t].parameter[p].info.parameter_max = -FLT_MAX; + field->tile[t].parameter[p].info.parameter_min = FLT_MAX; + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar sequence_packets(bwc_field *const field, bwc_field *const field) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! tile bwc_tile* - Structure defining a bwc tile. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 13.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uchar +sequence_packets(bwc_field *const field, bwc_tile *const tile) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 tile_size, idx; + uint32 j, p; + int32 r; + uint8 l; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + bwc_resolution *resolution; + bwc_packet **packet_sequence; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(tile); + + /*--------------------------------------------------------*\ + ! Save the global control and info as well as the packet ! + ! sequence structure to temporary variables to make the ! + ! code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = field->info; + + packet_sequence = tile->packet_sequence; + + switch(control->progression) + { + case bwc_prog_LRCP: + { + for(l = 0, tile_size = 0, idx = 0; l < control->nLayers; ++l) + { + for(r = 0; r < control->nDecomp + 1; ++r) + { + for(j = 0; j < info->nPar; ++j) + { + resolution = &tile->parameter[j].resolution[r]; + + for(p = 0; p < resolution->control.number_of_precincts; ++p, ++idx) + { + packet_sequence[idx] = &resolution->packet[l * resolution->control.number_of_precincts + p]; + tile_size += resolution->packet[l * resolution->control.number_of_precincts + p].size; + + if(control->error_resilience) + { + tile_size += 6; + } + } + } + } + } + break; + } + case bwc_prog_RLCP: + { + for(r = 0, tile_size = 0, idx = 0; r < control->nDecomp + 1; ++r) + { + for(l = 0; l < control->nLayers; ++l) + { + for(j = 0; j < info->nPar; ++j) + { + resolution = &tile->parameter[j].resolution[r]; + + for(p = 0; p < resolution->control.number_of_precincts; ++p, ++idx) + { + packet_sequence[idx] = &resolution->packet[l * resolution->control.number_of_precincts + p]; + tile_size += resolution->packet[l * resolution->control.number_of_precincts + p].size; + + if(control->error_resilience) + { + tile_size += 6; + } + } + } + } + } + break; + } + case bwc_prog_RPCL: + { + for(l = 0, tile_size = 0, idx = 0; l < control->nLayers; ++l) + { + for(r = 0; r < control->nDecomp + 1; ++r) + { + for(j = 0; j < info->nPar; ++j) + { + resolution = &tile->parameter[j].resolution[r]; + + for(p = 0; p < resolution->control.number_of_precincts; ++p, ++idx) + { + packet_sequence[idx] = &resolution->packet[l * resolution->control.number_of_precincts + p]; + tile_size += resolution->packet[l * resolution->control.number_of_precincts + p].size; + + if(control->error_resilience) + { + tile_size += 6; + } + } + } + } + } + break; + } + case bwc_prog_PCRL: + { + for(l = 0, tile_size = 0, idx = 0; l < control->nLayers; ++l) + { + for(r = 0; r < control->nDecomp + 1; ++r) + { + for(j = 0; j < info->nPar; ++j) + { + resolution = &tile->parameter[j].resolution[r]; + + for(p = 0; p < resolution->control.number_of_precincts; ++p, ++idx) + { + packet_sequence[idx] = &resolution->packet[l * resolution->control.number_of_precincts + p]; + tile_size += resolution->packet[l * resolution->control.number_of_precincts + p].size; + + if(control->error_resilience) + { + tile_size += 6; + } + } + } + } + } + break; + } + case bwc_prog_CPRL: + { + for(l = 0, tile_size = 0, idx = 0; l < control->nLayers; ++l) + { + for(r = 0; r < control->nDecomp + 1; ++r) + { + for(j = 0; j < info->nPar; ++j) + { + resolution = &tile->parameter[j].resolution[r]; + + for(p = 0; p < resolution->control.number_of_precincts; ++p, ++idx) + { + packet_sequence[idx] = &resolution->packet[l * resolution->control.number_of_precincts + p]; + tile_size += resolution->packet[l * resolution->control.number_of_precincts + p].size; + + if(control->error_resilience) + { + tile_size += 6; + } + } + } + } + } + break; + } + default: + { + return 1; + } + } + + tile->control.body_size = tile_size; + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar sequence_packets(bwc_field *const field, bwc_field *const field) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! tile bwc_tile* - Structure defining a bwc tile. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 13.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +assemble_tile(bwc_field *const field, bwc_tile *const tile, bwc_stream *const stream) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 packet_index; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_packet *packet; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(tile); + assert(stream); + + /*--------------------------------------------------------*\ + ! Save the global control and info as well as the packet ! + ! sequence structure to temporary variables to make the ! + ! code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + bwc_emit_symbol(stream, SOT, 2); + bwc_emit_symbol(stream, 14, 2); + bwc_emit_symbol(stream, tile->info.tile_index, 4); + bwc_emit_symbol(stream, tile->control.body_size, 8); + bwc_emit_symbol(stream, SOD, 2); + + for(packet_index = 0; packet_index < tile->control.nPackets; ++packet_index) + { + packet = tile->packet_sequence[packet_index]; + + if(control->error_resilience) + { + bwc_emit_symbol(stream, SOP, 2); + bwc_emit_symbol(stream, 4, 2); + bwc_emit_symbol(stream, packet_index % 0x100000000, 4); + } + + if(packet->header.memory) + { + bwc_emit_chunck(stream, packet->header.memory, packet->header.size); + + if(control->error_resilience) + { + bwc_emit_symbol(stream, EPH, 2); + } + + release_packed_stream(&packet->header); + } + + if(packet->body.memory) + { + bwc_emit_chunck(stream, packet->body.memory, packet->body.size); + + release_packed_stream(&packet->body); + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar sequence_packets(bwc_field *const field, bwc_field *const field) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! tile bwc_tile* - Structure defining a bwc tile. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 13.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uchar +parse_tile(bwc_field *const field, bwc_stream *const stream) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 body_size; + uint64 packet_index; + uint64 buf; + uint32 L; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_packet *packet; + bwc_tile *tile; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(stream); + + /*--------------------------------------------------------*\ + ! Save the global control and info as well as the packet ! + ! sequence structure to temporary variables to make the ! + ! code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + if(!can_read(stream, 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + return 1; + } + + L = (uint16)bwc_get_symbol(stream, 2); + + if(!can_read(stream, L - 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + return 1; + } + + buf = (uint32)bwc_get_symbol(stream, 4); + if(buf >= control->nTiles) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + return 1; + } + + tile = &field->tile[buf]; + tile->control.body_size = + body_size = (uint64)bwc_get_symbol(stream, 8); + + if(SOD != (uint16)bwc_get_symbol(stream, 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + return 1; + } + else + { + /*--------------------------------------------------------*\ + ! Sequence the packets according to the user specified op- ! + ! tion. ! + \*--------------------------------------------------------*/ + if(sequence_packets(field, tile)) + { + return 1; + } + + packet_index = 0; + + while((body_size != 0) && can_read(stream, body_size) && packet_index < tile->control.nPackets) + { + if(SOP == (uint16)bwc_get_symbol(stream, 2)) + { + if(!can_read(stream, 6)) + { + //Invalid Codestream + fprintf(stderr, CSERROR); + return 1; + } + + if(4 != (uint16)bwc_get_symbol(stream, 2)) + { + //Invalid Codestream + fprintf(stderr, CSERROR); + return 1; + } + + buf = (uint32)bwc_get_symbol(stream, 4); + + body_size -= 8; + } + else + { + rewind_stream(stream, 2); + } + + packet = tile->packet_sequence[packet_index++]; + + packet->header.memory = get_access(stream); + + if(parse_packet(field, tile, packet, body_size)) + { + return 1; + } + + forward_stream(stream, packet->size); + + body_size -= packet->size; + } + } + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uchar +parse_body(bwc_field *const field, bwc_stream *const stream) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint16 Lunk; + uint16 marker; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char status; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + status = CODESTREAM_OK; + + while(!(status & CODESTREAM_ERROR) && can_read(stream, 2)) + { + marker = (uint16)bwc_get_symbol(stream, 2); + if(marker < 0xFF00) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + status |= CODESTREAM_ERROR; + } + + switch(marker) + { + case SOT: + { + if(parse_tile(field, stream)) + { + status |= CODESTREAM_ERROR; + } + break; + } + + case EOC: + { + return 0; + break; + } + + case SOC: + case SGI: + case SGC: + case SAX: + case COM: + case EOH: + { + // Invalid Codestream + fprintf(stderr, CSERROR); + status |= CODESTREAM_ERROR; + + break; + } + + default: + { + if(!can_read(stream, 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + Lunk = (uint16)bwc_get_symbol(stream, 2); + if(!can_read(stream, Lunk - 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + stream->L += Lunk - 2; + break; + } + } + } + return 0; +} +/************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +assemble_main_header(bwc_field *const field) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 size; + uint16 Linf, Lctr; + uint8 p, l; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + bwc_tile *tile; + bwc_parameter *parameter; + bwc_stream *stream; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global as well as the subband control and info ! + ! structure to temporary variables to make the code more ! + ! readable. ! + \*--------------------------------------------------------*/ + info = field->info; + control = &field->control; + + tile = &field->tile[0]; + + parameter = &tile->parameter[0]; + + Linf = 40 + info->nPar * 29; + Lctr = 50 + control->nLayers * 4; + + size = 6 + Linf + Lctr; + + stream = bwc_init_stream(NULL, size, 'c'); + if(!stream) + { + // memory allocation error + return 1; + } + + bwc_emit_symbol(stream, SOC, 2); + bwc_emit_symbol(stream, SGI, 2); + bwc_emit_symbol(stream, Linf, 2); + bwc_emit_symbol(stream, info->nX, 8); + bwc_emit_symbol(stream, info->nY, 8); + bwc_emit_symbol(stream, info->nZ, 8); + bwc_emit_symbol(stream, info->nTS, 2); + bwc_emit_symbol(stream, info->nPar, 1); + bwc_emit_symbol(stream, info->precision, 1); + bwc_emit_chunck(stream, (uchar*)info->f_ext, 10); + + for(p = 0; p < info->nPar; ++p) + { + bwc_emit_chunck(stream, (uchar*)parameter[p].info.name, 24); + bwc_emit_symbol(stream, parameter[p].control.sampX, 1); + bwc_emit_symbol(stream, parameter[p].control.sampY, 1); + bwc_emit_symbol(stream, parameter[p].control.sampZ, 1); + bwc_emit_symbol(stream, parameter[p].control.sampTS, 1); + bwc_emit_symbol(stream, parameter[p].info.precision, 1); + } + + bwc_emit_symbol(stream, SGC, 2); + bwc_emit_symbol(stream, Lctr, 2); + + bwc_emit_symbol(stream, control->CSsgc, 2); + + bwc_emit_symbol(stream, control->error_resilience, 1); + + bwc_emit_symbol(stream, control->quantization_style, 1); + bwc_emit_symbol(stream, control->guard_bits, 1); + + bwc_emit_symbol(stream, control->qt_exponent, 1); + bwc_emit_symbol(stream, control->qt_mantissa, 2); + + bwc_emit_symbol(stream, control->progression, 1); + bwc_emit_symbol(stream, control->KernelX << 6 | control->KernelY << 4 | + control->KernelZ << 2 | control->KernelTS, 1); + + bwc_emit_symbol(stream, control->decompX, 1); + bwc_emit_symbol(stream, control->decompY, 1); + bwc_emit_symbol(stream, control->decompZ, 1); + bwc_emit_symbol(stream, control->decompTS, 1); + + bwc_emit_symbol(stream, control->precSizeY << 4 | control->precSizeX, 1); + bwc_emit_symbol(stream, control->precSizeTS << 4 | control->precSizeZ, 1); + + bwc_emit_symbol(stream, control->cbX, 1); + bwc_emit_symbol(stream, control->cbY, 1); + bwc_emit_symbol(stream, control->cbZ, 1); + bwc_emit_symbol(stream, control->cbTS, 1); + + bwc_emit_symbol(stream, control->Qm, 1); + + bwc_emit_symbol(stream, control->tileSizeX, 8); + bwc_emit_symbol(stream, control->tileSizeY, 8); + bwc_emit_symbol(stream, control->tileSizeZ, 8); + bwc_emit_symbol(stream, control->tileSizeTS, 2); + + bwc_emit_symbol(stream, control->nLayers, 1); + + for(l = 0; l < control->nLayers; ++l) + { + bwc_emit_symbol(stream, *(uint32 *)&control->bitrate[l], 4); + } + + if(bwc_terminate_stream(stream, &control->header)) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +bwc_field* +bwc_parse_main_header(bwc_data *const data,bwc_stream *const stream) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 buff_long, buffX, buffY, buffZ, buffTS; + uint64 nX, nY, nZ; + uint32 buff; + uint32 bitrate; + uint32 Lsax; + uint32 mantissa, exponent; + uint32 t; + uint16 CSsgc; + uint16 Linf, Lctr, Lcom, Leoh, Lunk; + uint16 marker; + uint16 nTS; + uint8 dim; + uint8 index, l; + uint8 samp; + uint8 nPar, p; + uint8 codec_prec, precision; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char* buffer_char; + char status; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_field *field; + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(data); + assert(stream); + + /*--------------------------------------------------------*\ + ! Save the data info structure to a temporary variable to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + info = &data->info; + + status = CODESTREAM_OK; + index = 0; + + while(!(status & CODESTREAM_ERROR) && can_read(stream, 2)) + { + marker = (uint16)bwc_get_symbol(stream, 2); + if(marker < 0xFF00) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + status |= CODESTREAM_ERROR; + } + + switch(marker) + { + case SOC: + { + if(index != 0) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + status |= CODESTREAM_ERROR; + } + break; + } + + case SGI: + { + if(index != 1 && !can_read(stream, 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + status |= CODESTREAM_ERROR; + break; + } + + Linf = (uint16)bwc_get_symbol(stream, 2); + if(!can_read(stream, Linf - 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + status |= CODESTREAM_ERROR; + break; + } + + info->nX = nX = bwc_get_symbol(stream, 8); + info->nY = nY = bwc_get_symbol(stream, 8); + info->nZ = nZ = bwc_get_symbol(stream, 8); + info->nTS = nTS = (uint16)bwc_get_symbol(stream, 2); + info->nPar = nPar = (uint8)bwc_get_symbol(stream, 1); + info->precision = codec_prec = (uint8)bwc_get_symbol(stream, 1); + + buffer_char = (char*)bwc_get_chunck(stream, 10); + strncpy(info->f_ext, buffer_char, sizeof(buffer_char)/sizeof(*buffer_char)); + free(buffer_char); + + for(p = 0; p < nPar; ++p) + { + buffer_char = (char*)bwc_get_chunck(stream, 24); + + samp = (uint8)bwc_get_symbol(stream, 1); + dim = DIM_X; + + buff_long = bwc_get_symbol(stream, 1); + samp = (buff_long > samp) ? (uint8)buff_long : samp; + dim = (buff_long > samp) ? DIM_Y : (buff_long == samp) ? dim | DIM_Y : dim; + + buff_long = bwc_get_symbol(stream, 1); + samp = (buff_long > samp) ? (uint8)buff_long : samp; + dim = (buff_long > samp) ? DIM_Z : (buff_long == samp) ? dim | DIM_Z : dim; + + buff_long = bwc_get_symbol(stream, 1); + samp = (buff_long > samp) ? (uint8)buff_long : samp; + dim = (buff_long > samp) ? DIM_TS : (buff_long == samp) ? dim | DIM_TS : dim; + + precision = (uint8)bwc_get_symbol(stream, 1); + + bwc_add_param(data, buffer_char, samp, dim, precision); + + free(buffer_char); + } + + field = bwc_initialize_field(data); + if(!field) + { + status |= CODESTREAM_ERROR; + break; + } + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + info = field->info = &data->info; + control = &field->control; + + status |= CODESTREAM_SGI_READ; + break; + } + + case SGC: + { + if(index != 2 && !can_read(stream, 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + Lctr = (uint16)bwc_get_symbol(stream, 2); + + if(!can_read(stream, Lctr - 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + CSsgc = (uint16)bwc_get_symbol(stream, 2); + + + buff_long = bwc_get_symbol(stream, 1); + if(CSsgc & (0x01 << 0)) + { + bwc_set_error_resilience(field); + } + + buff_long = bwc_get_symbol(stream, 1); + + if(CSsgc & (0x01 << 1)) + { + bwc_set_quantization_style(field, (bwc_quant_st)buff_long); + } + + buff_long = bwc_get_symbol(stream, 1); + + exponent = (uint32)bwc_get_symbol(stream, 1); + mantissa = (uint32)bwc_get_symbol(stream, 2); + if(CSsgc & (0x01 << 2)) + { + control->qt_exponent = exponent; + control->qt_mantissa = mantissa; + } + + buff_long = bwc_get_symbol(stream, 1); + if(CSsgc & (0x01 << 3)) + { + bwc_set_progression(field, (uint8)buff_long); + } + + buff_long = bwc_get_symbol(stream, 1); + if(CSsgc & (0x01 << 4)) + { + bwc_set_kernels(field, (uint8)(0x03 & (buff_long >> 6)), (uint8)(0x03 & (buff_long >> 4)), + (uint8)(0x03 & (buff_long >> 2)), (uint8)(0x03 & buff_long)); + } + + buff_long = bwc_get_symbol(stream, 4); + if(CSsgc & (0x01 << 5)) + { + bwc_set_decomp(field, (uint8)(0xFF & (buff_long >> 24)), (uint8)(0xFF & (buff_long >> 16)), + (uint8)(0xFF & (buff_long >> 8)), (uint8)(0xFF & buff_long)); + } + + buff_long = bwc_get_symbol(stream, 2); + if(CSsgc & (0x01 << 6)) + { + bwc_set_precincts(field, (uint8)(0x0F & (buff_long >> 8)), (uint8)(0x0F & (buff_long >> 12)), + (uint8)(0x0F & buff_long), (uint8)(0x0F & (buff_long >> 4))); + } + + buff_long = bwc_get_symbol(stream, 4); + if(CSsgc & (0x01 << 7)) + { + bwc_set_codeblocks(field, (uint8)(0xFF & (buff_long >> 24)), (uint8)(0xFF & (buff_long >> 16)), + (uint8)(0xFF & (buff_long >> 8)), (uint8)(0xFF & buff_long)); + } + + buff_long = bwc_get_symbol(stream, 1); + if(CSsgc & (0x01 << 8)) + { + bwc_set_qm(field, (uint8)buff_long); + } + + buffX = bwc_get_symbol(stream, 8); + buffY = bwc_get_symbol(stream, 8); + buffZ = bwc_get_symbol(stream, 8); + buffTS = bwc_get_symbol(stream, 2); + if(CSsgc & (0x01 << 9)) + { + bwc_set_tiles(field, buffX, buffY, buffZ, (uint16)buffTS, bwc_tile_sizeof); + } + + control->nLayers = bwc_get_symbol(stream, 1); + control->bitrate = calloc(control->nLayers, sizeof(float)); + if(!control->bitrate) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_kill_compression(field); + status|= CODESTREAM_ERROR; + break; + } + + for(l = 0; l < control->nLayers; ++l) + { + bitrate = (uint32)bwc_get_symbol(stream, 4); + control->bitrate[l] = *(float *)&bitrate; + } + + create_field(field); + if(!field) + { + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + status |= CODESTREAM_SGC_READ; + break; + } + + case SAX: + { + if(index <= 2 && !can_read(stream, 4)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + Lsax = (uint32)bwc_get_symbol(stream, 4); + if(!can_read(stream, Lsax - 4)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + data->codestream.aux = calloc(1, sizeof(bwc_packed_stream)); + if(!data->codestream.aux) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + data->codestream.aux->memory = bwc_get_chunck(stream, Lsax - 4); + data->codestream.aux->size = Lsax - 4; + + status |= CODESTREAM_SAX_READ; + break; + } + + case COM: + { + if(index <= 2 && !can_read(stream, 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + Lcom = (uint16)bwc_get_symbol(stream, 2); + if(!can_read(stream, Lcom - 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + data->codestream.com = calloc(1, sizeof(bwc_packed_stream)); + if(!data->codestream.com) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + data->codestream.com->memory = bwc_get_chunck(stream, Lcom - 2); + data->codestream.com->size = Lcom -2; + + status |= CODESTREAM_ERROR; + break; + } + + case EOH: + { + if((status & CODESTREAM_SGI_READ) && (status & CODESTREAM_SGC_READ)) + { + if(index <= 2 && !can_read(stream, 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + Leoh = (uint16)bwc_get_symbol(stream, 2); + if(!can_read(stream, Leoh - 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + if(codec_prec == 8) + { + /*--------------------------------------------------------*\ + ! Loop through all tile parameters and... ! + \*--------------------------------------------------------*/ + for(t = 0; t < control->nTiles; ++t) + { + for(p = 0; p < info->nPar; ++p) + { + /*--------------------------------------------------------*\ + ! ...get the maximum and minimum parameter value to the ! + ! header stream. ! + \*--------------------------------------------------------*/ + buff_long = bwc_get_symbol(stream, sizeof(double)); + field->tile[t].parameter[p].info.parameter_min = (bwc_float)*(double*)&buff_long; + + buff_long = bwc_get_symbol(stream, sizeof(double)); + field->tile[t].parameter[p].info.parameter_max = (bwc_float)*(double*)&buff_long; + } + } + } + else if(codec_prec == 4) + { + /*--------------------------------------------------------*\ + ! Loop through all tile parameters and... ! + \*--------------------------------------------------------*/ + for(t = 0; t < control->nTiles; ++t) + { + for(p = 0; p < info->nPar; ++p) + { + /*--------------------------------------------------------*\ + ! ...get the maximum and minimum parameter value to the ! + ! header stream. ! + \*--------------------------------------------------------*/ + buff = bwc_get_symbol(stream, sizeof(float)); + field->tile[t].parameter[p].info.parameter_min = (bwc_float)*(float*)&buff; + + buff = bwc_get_symbol(stream, sizeof(float)); + field->tile[t].parameter[p].info.parameter_max = (bwc_float)*(float*)&buff; + } + } + } + return field; + } + else + { + // Invalid Codestream + fprintf(stderr, CSERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + } + break; + } + + default: + { + if(!can_read(stream, 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + Lunk = (uint16)bwc_get_symbol(stream, 2); + if(!can_read(stream, Lcom - 2)) + { + // Invalid Codestream + fprintf(stderr, CSERROR); + bwc_kill_compression(field); + status |= CODESTREAM_ERROR; + break; + } + + stream->L += Lunk - 2; + break; + } + } + index++; + } + return NULL; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +codestream_write_aux(bwc_packed_stream *const header, bwc_packed_stream *const aux) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint32 Laux; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_stream *stream; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(header); + assert(aux); + + stream = bwc_init_stream(header->memory, header->size, 'c'); + if(!stream) + { + // memory allocation error + return 1; + } + + Laux = aux->size + 4; + + stream->L = stream->Lmax; + stream->Lmax += Laux + 2; + stream->memory = realloc(stream->memory, stream->Lmax); + if(!stream->memory) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + bwc_emit_symbol(stream, SAX, 2); + bwc_emit_symbol(stream, Laux, 4); + bwc_emit_chunck(stream, aux->memory, aux->size); + + if(bwc_terminate_stream(stream, header)) + { + // memory allocation error + return 1; + } + + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +codestream_write_com(bwc_packed_stream *const header, bwc_packed_stream *const com) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint16 Lcom; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_stream *stream; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(header); + assert(com); + + stream = bwc_init_stream(header->memory, header->size, 'c'); + if(!stream) + { + // memory allocation error + return 1; + } + + Lcom = com->size + 2; + + stream->L = stream->Lmax; + stream->Lmax += Lcom + 2; + stream->memory = realloc(stream->memory, stream->Lmax); + if(!stream->memory) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + bwc_emit_symbol(stream, COM, 2); + bwc_emit_symbol(stream, Lcom, 2); + bwc_emit_chunck(stream, com->memory, com->size); + + if(bwc_terminate_stream(stream, header)) + { + // memory allocation error + return 1; + } + + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: bwc_packed_stream* assemble_codestream(bwc_field *const field) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! bwc_packed_stream* - Packed stream containing the compressed data set. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 13.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +bwc_packed_stream* +assemble_codestream(bwc_field *const field) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i, size; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_tile *tile; + bwc_stream *stream; + bwc_packed_stream *packed_stream; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable and initialize ! + ! the final codestream size with the number of header ! + ! bytes. ! + \*--------------------------------------------------------*/ + control = &field->control; + size = control->header.size; + + /*--------------------------------------------------------*\ + ! Walk through the tile structure and assemble the packed ! + ! data stream. ! + \*--------------------------------------------------------*/ + for(i = 0; i < control->nTiles; ++i) + { + /*--------------------------------------------------------*\ + ! Save the tile structure in a temporary variable to make ! + ! the code more readable. ! + \*--------------------------------------------------------*/ + tile = &field->tile[i]; + + /*--------------------------------------------------------*\ + ! Sequence the packets according to the user specified op- ! + ! tion and iterate the size of the codestream. ! + \*--------------------------------------------------------*/ + if(sequence_packets(field, tile)) + { + return NULL; + } + + size += tile->control.header_size + tile->control.body_size; + } + + /*--------------------------------------------------------*\ + ! Initialize the final codestream and emit the header ! + ! bytes. ! + \*--------------------------------------------------------*/ + stream = bwc_init_stream(NULL, size, 'c'); + codestream_write_header(stream, field); + + /*--------------------------------------------------------*\ + ! Walk through the tile structure and assemble the packed ! + ! data stream. ! + \*--------------------------------------------------------*/ + for(i = 0; i < control->nTiles; ++i) + { + /*--------------------------------------------------------*\ + ! Save the tile structure in a temporary variable to make ! + ! the code more readable. ! + \*--------------------------------------------------------*/ + tile = &field->tile[i]; + + assemble_tile(field, tile, stream); + } + + bwc_emit_symbol(stream, EOC, 2); + + packed_stream = calloc(1, sizeof(bwc_packed_stream)); + if(!packed_stream) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return NULL; + } + + if(bwc_terminate_stream(stream, packed_stream)) + { + return NULL; + } + else + { + return packed_stream; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar parse_codestream(bwc_field *const field, bwc_stream *const stream) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! stream bwc_stream* - Structure used to assemble a bwc bit- ! +! bitstream. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 05.08.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +bwc_field* +parse_codestream(bwc_data *const data, uint8 const layer) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_field *field; + bwc_stream *stream; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(data); + + /*--------------------------------------------------------*\ + ! Initialize a bitstream used to parse the packed code- ! + ! stream. ! + \*--------------------------------------------------------*/ + stream = bwc_init_stream(data->codestream.data->memory, + data->codestream.data->size, 'd'); + + /*--------------------------------------------------------*\ + ! Parse the main header and set up the field structure for ! + ! the current decompression run. ! + \*--------------------------------------------------------*/ + field = bwc_parse_main_header(data, stream); + if(!field) + { + return NULL; + } + + /*--------------------------------------------------------*\ + ! Initialize the useLayer option to decompress the entire ! + ! codestream. ! + \*--------------------------------------------------------*/ + field->control.useLayer = field->control.nLayers - 1; + + /*--------------------------------------------------------*\ + ! Check if the layer index supplied by the function caller ! + ! is valid. ! + \*--------------------------------------------------------*/ + if(layer < field->control.nLayers && layer > 0) + { + /*--------------------------------------------------------*\ + ! Amend the use layer variable in the global control struc-! + ! ture. ! + \*--------------------------------------------------------*/ + field->control.useLayer = layer; + } + + /*--------------------------------------------------------*\ + ! Parse the rest of the compressed codestream and load the ! + ! body into the field structure. ! + \*--------------------------------------------------------*/ + if(parse_body(field, stream)) + { + bwc_kill_compression(field); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Free the bitstream used to parse the codestream and re- ! + ! turn the field structure to the function caller. ! + \*--------------------------------------------------------*/ + free(stream); + + return field; +} \ No newline at end of file diff --git a/src/library/dwt.c b/src/library/dwt.c new file mode 100755 index 0000000..de9a7c1 --- /dev/null +++ b/src/library/dwt.c @@ -0,0 +1,2681 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| FILE NAME: dwt.c || +|| || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| FILE REFERENCES: || +|| ---------------- || +|| || +|| Name I/O Description || +|| ---- --- ----------- || +|| none - - || +|| || +|| || +|| PRIVATE FUNCTIONS: || +|| ------------------ || +|| - get_filter_taps || +|| - fill_forward_buffer || +|| - fill_inverse_buffer || +|| - whole_point_symmetric_extend || +|| - forward_9x7_CDF_wavelet_transform || +|| - inverse_9x7_CDF_wavelet_transform || +|| - forward_5x3_LeGall_wavelet_transform || +|| - inverse_5x3_LeGall_wavelet_transform || +|| - forward_Haar_wavelet_transform || +|| - inverse_Haar_wavelet_transform || +|| - buffer_flush_forward || +|| - buffer_flush_inverse || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| - initialize_gain_lut || +|| - get_dwt_energy_gain || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 19.03.2018 Patrick Vogler B87D120 V 0.1.0 source file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ + +/************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\************************************************************************************************************/ +#include +#include +#include +#include +#include + +#include "constants.h" +#include "macros.h" +#include "types.h" +#include "dwt.h" + +/************************************************************************************************************\ +|| ____ _ _ ___ ____ ____ _ _ ____ _ _ _ ____ ____ _ ____ ___ _ ____ ____ || +|| |___ \/ | |___ |__/ |\ | |__| | | | |__| |__/ | |__| |__] | |___ [__ || +|| |___ _/\_ | |___ | \ | \| | | |___ \/ | | | \ | | | |__] |___ |___ ___] || +|| || +\************************************************************************************************************/ +double DWT_ENERGY_GAIN_LUT[3][2 * MAX_DECOMPOSITION_LEVELS + 2]; + +/************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uint8 get_max_taps(bwc_gl_ctrl *const control) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function returns the rounded up maximum half length of the specified wavelet filter. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! dwt_filter bwc_dwt_filter - Specifies the wavelet kernels used for ! +! spatial decomposition. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uint8 - Specifies the rounded up maximum half-length of a wavelet fil- ! +! ter. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 22.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uint8 +get_filter_taps(bwc_dwt_filter dwt_filter) +{ + /*--------------------------------------------------------*\ + ! Emit the rounded up maximum half-length of the specified ! + ! wavelet filter. ! + \*--------------------------------------------------------*/ + switch(dwt_filter) + { + case bwc_dwt_9_7: + { + return 4; + } + case bwc_dwt_5_3: + { + return 2; + } + case bwc_dwt_haar: + { + return 1; + } + default: + { + assert(0); + return 0; + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void fill_forward_buffer(bwc_sample *const data, bwc_sample *const working_buffer, ! +! ------------ uint64 res0, ! +! uint64 res1, ! +! uint64 increment) ! +! ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to fill the working buffer with the appropriate flow field data for ! +! the forward one dimensional wavelet transform. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! data bwc_sample* - Pointer to the flow field data of the ! +! current tile parameter. ! +! ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for the one dimensional dwt. ! +! ! +! res0 unsigned int(64 bit) - Starting point for the current resolu- ! +! tion and dimension. ! +! ! +! res1 unsigned int(64 bit) - End point for the current resolution ! +! and dimension. ! +! ! +! increment unsigned int(64 bit) - Data increment for strided memory ac- ! +! cess. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 24.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +fill_forward_buffer(bwc_sample *const data, bwc_sample *const working_buffer, uint64 res0, uint64 res1, uint64 increment) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i, j; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(data); + assert(working_buffer); + + /*--------------------------------------------------------*\ + ! Copy the strided memory for the current resolution and ! + ! dimension from the tile parameter buffer to the working ! + ! buffer for the one dimensional wavelet transform. ! + \*--------------------------------------------------------*/ + for(i = 0, j = 0; i < res1 - res0; ++i) + { + working_buffer[i] = data[j]; + j += increment; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void fill_inverse_buffer(bwc_sample *const data, bwc_sample *const working_buffer, ! +! ------------ uint64 res0, ! +! uint64 res1, ! +! uint64 increment) ! +! ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to fill the working buffer with the appropriate flow field data for ! +! the inverse one dimensional wavelet transform. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! data bwc_sample* - Pointer to the flow field data of the ! +! current tile parameter. ! +! ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for the one dimensional dwt. ! +! ! +! res0 unsigned int(64 bit) - Starting point for the current resolu- ! +! tion and dimension. ! +! ! +! res1 unsigned int(64 bit) - End point for the current resolution ! +! and dimension. ! +! ! +! increment unsigned int(64 bit) - Data increment for strided memory ac- ! +! cess. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 24.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +fill_inverse_buffer(bwc_sample *const data, bwc_sample *const working_buffer, uint64 res0, uint64 res1, uint64 increment) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, length, half_length; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_sample *lowband, *highband; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(data); + assert(working_buffer); + + /*--------------------------------------------------------*\ + ! Calculate the length and half_length of the buffer. ! + \*--------------------------------------------------------*/ + length = res1 - res0; + half_length = (res0 % 2) ? length >> 1 : (length + 1) >> 1; + + /*--------------------------------------------------------*\ + ! Associate the data pointers to the starting point of the ! + ! low- and highband. ! + \*--------------------------------------------------------*/ + lowband = data; + highband = data + half_length * increment; + + /*--------------------------------------------------------*\ + ! Check if the starting point is odd. ! + \*--------------------------------------------------------*/ + if((res0 % 2) == 0) + { + /*--------------------------------------------------------*\ + ! Loop over the lowband wavelet coefficients in the tile ! + ! parameter memory and interleave them into the working ! + ! buffer. ! + \*--------------------------------------------------------*/ + for(i = 0; i < half_length; ++i) + { + working_buffer[i << 1].f = lowband->f; + lowband += increment; + } + + /*--------------------------------------------------------*\ + ! Decrease the half length in case of an odd resolution ! + ! length to account for the half-length - 1 number of ! + ! highband wavelet coefficients. ! + \*--------------------------------------------------------*/ + if(length % 2) --half_length; + + /*--------------------------------------------------------*\ + ! Loop over the highband wavelet coefficients in the tile ! + ! parameter memory and interleave them into the working ! + ! buffer. ! + \*--------------------------------------------------------*/ + for(i = 0; i < half_length; ++i) + { + working_buffer[(i << 1) + 1].f = highband->f; + highband += increment; + } + } + else + { + /*--------------------------------------------------------*\ + ! Loop over the lowband wavelet coefficients in the tile ! + ! parameter memory and interleave them into the working ! + ! buffer. ! + \*--------------------------------------------------------*/ + for(i = 0; i < half_length; ++i) + { + working_buffer[i << 1].f = lowband->f; + lowband += increment; + } + + /*--------------------------------------------------------*\ + ! Increase the half length in case of an even resolution ! + ! length to account for the half-length + 1 number of ! + ! highband wavelet coefficients. ! + \*--------------------------------------------------------*/ + if(length % 2) ++half_length; + + /*--------------------------------------------------------*\ + ! Loop over the highband wavelet coefficients in the tile ! + ! parameter memory and interleave them into the working ! + ! buffer. ! + \*--------------------------------------------------------*/ + for(i = 0; i < half_length; ++i) + { + working_buffer[(i << 1) + 1].f = highband->f; + highband += increment; + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void whole_point_symmetric_extend(bwc_sample *const working_buffer, uint64 res0, ! +! ------------ uint64 res1, ! +! uint8 nTaps) ! +! ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to fill the boundary values of the working buffer with appropriate ! +! flow field data using a symmetric whole point extension: ! +! ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ! +! |___|___|___||_A_|_B_|_C_|_D_|_E_| ... |_V_|_W_|_X_|_Y_|_Z_||___|___|___| ! +! | ! +! | ! +! \|/ ! +! ___ ___ ___ ___ ___ ___ ___ ___ V ___ ___ ___ ___ ___ ___ ___ ___ ! +! |_E_|_C_|_B_||_A_|_B_|_C_|_D_|_E_| ... |_V_|_W_|_X_|_Y_|_Z_||_Y_|_X_|_W_| ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for the one dimensional dwt. ! +! ! +! res0 unsigned int(64 bit) - Starting point for the current resolu- ! +! tion and dimension. ! +! ! +! res1 unsigned int(64 bit) - End point for the current resolution ! +! and dimension. ! +! ! +! nTaps unsigned int(8 bit) - Maximum half length of a wavelet filter.! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +whole_point_symmetric_extend(bwc_sample *const working_buffer, uint64 res0, uint64 res1, uint8 nTaps) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i, length; + int64 j, min, max; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(working_buffer); + + length = res1 - res0; + + if(nTaps < length) + { + for(i = 0; i < nTaps; ++i) + { + working_buffer[i - nTaps] = working_buffer[nTaps - i]; + working_buffer[length + i] = working_buffer[length - (i + 2)]; + } + } + else + { + min = nTaps; + max = nTaps + length - 1; + + for(i = 0; i < nTaps; ++i) + { + j = i; + + while (j < min || j > max) + { + if(j < min) j = (min << 1) - j; + else j = (max << 1) - j; + } + working_buffer[i - nTaps] = working_buffer[j - nTaps]; + + j = i + length + nTaps; + + while (j < min || j > max) + { + if(j < min) j = (min << 1) - j; + else j = (max << 1) - j; + } + working_buffer[i + length] = working_buffer[j - nTaps]; + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void forward_9x7_CDF_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, ! +! ------------ uint64 res1) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function applies the forward (9-7) Cohen-Daubechies-Feauveau wavelet transform on the ! +! data samples stored in the working buffer. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for the one dimensional dwt. ! +! ! +! res0 unsigned int(64 bit) - Starting point for the current resolu- ! +! tion and dimension. ! +! ! +! res1 unsigned int(64 bit) - End point for the current resolution ! +! and dimension. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +forward_9x7_CDF_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, uint64 res1) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, length; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(working_buffer); + + length = res1 - res0; + + /*--------------------------------------------------------*\ + ! Perform the first predictor step on the odd samples. ! + \*--------------------------------------------------------*/ + for(i = -3; i < length + 3; i += 2) + { + working_buffer[i].f += ALPHA * (working_buffer[i - 1].f + working_buffer[i + 1].f); + } + + /*--------------------------------------------------------*\ + ! Perform the first update step on the even samples. ! + \*--------------------------------------------------------*/ + for(i = -2; i < length + 2; i += 2) + { + working_buffer[i].f += BETA * (working_buffer[i - 1].f + working_buffer[i + 1].f); + } + + /*--------------------------------------------------------*\ + ! Perform the second predictor and scaling step on the odd ! + ! samples. ! + \*--------------------------------------------------------*/ + for(i = -1; i < length + 1; i += 2) + { + working_buffer[i].f += GAMMA * (working_buffer[i - 1].f + working_buffer[i + 1].f); + working_buffer[i].f = KAPPA_H * working_buffer[i].f; + } + + /*--------------------------------------------------------*\ + ! Perform the second update and scaling step on the even ! + ! samples. The delta coefficient has been modified to ! + ! account for the scaling step on the even samples. ! + \*--------------------------------------------------------*/ + for(i = 0; i < length; i += 2) + { + working_buffer[i].f += DELTA * (working_buffer[i - 1].f + working_buffer[i + 1].f); + working_buffer[i].f = KAPPA_L * working_buffer[i].f; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void inverse_9x7_CDF_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, ! +! ------------ uint64 res1) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function applies the inverse (9-7) Cohen-Daubechies-Feauveau wavelet transform on the ! +! data samples stored in the working buffer. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for the one dimensional dwt. ! +! ! +! res0 unsigned int(64 bit) - Starting point for the current resolu- ! +! tion and dimension. ! +! ! +! res1 unsigned int(64 bit) - End point for the current resolution ! +! and dimension. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +inverse_9x7_CDF_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, uint64 res1) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, length; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(working_buffer); + + length = res1 - res0; + + /*--------------------------------------------------------*\ + ! Perform the second update and scaling step on the even ! + ! samples. The delta coefficient has been modified to ! + ! account for the scaling step on the even samples. ! + \*--------------------------------------------------------*/ + for(i = -4; i < length + 4; i += 2) + { + working_buffer[i].f = KAPPA_H * working_buffer[i].f; + working_buffer[i].f -= DELTA * (working_buffer[i - 1].f + working_buffer[i + 1].f); + } + + /*--------------------------------------------------------*\ + ! Perform the second predictor and scaling step on the odd ! + ! samples. ! + \*--------------------------------------------------------*/ + for(i = -5; i < length + 3; i += 2) + { + working_buffer[i].f = KAPPA_L * working_buffer[i].f; + working_buffer[i].f -= GAMMA * (working_buffer[i - 1].f + working_buffer[i + 1].f); + } + + /*--------------------------------------------------------*\ + ! Perform the first update step on the even samples. ! + \*--------------------------------------------------------*/ + for(i = -4; i < length + 2; i += 2) + { + working_buffer[i].f -= BETA * (working_buffer[i - 1].f + working_buffer[i + 1].f); + } + + /*--------------------------------------------------------*\ + ! Perform the first predictor step on the odd samples. ! + \*--------------------------------------------------------*/ + for(i = -3; i < length + 1; i += 2) + { + working_buffer[i].f -= ALPHA * (working_buffer[i - 1].f + working_buffer[i + 1].f); + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void forward_5x3_LeGall_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, ! +! ------------ uint64 res1) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function applies the forward (5-3) LeGall wavelet transform on the data samples stored ! +! in the working buffer. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for the one dimensional dwt. ! +! ! +! res0 unsigned int(64 bit) - Starting point for the current resolu- ! +! tion and dimension. ! +! ! +! res1 unsigned int(64 bit) - End point for the current resolution ! +! and dimension. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +forward_5x3_LeGall_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, uint64 res1) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, length; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(working_buffer); + + length = res1 - res0; + + /*--------------------------------------------------------*\ + ! Perform the predictor step on the odd samples. ! + \*--------------------------------------------------------*/ + for(i = -1; i < length + 1; i += 2) + { + working_buffer[i].f -= (working_buffer[i - 1].f + working_buffer[i + 1].f) / 2; + } + + /*--------------------------------------------------------*\ + ! Perform the update step on the even samples. ! + \*--------------------------------------------------------*/ + for(i = 0; i < length; i += 2) + { + working_buffer[i].f += (working_buffer[i - 1].f + working_buffer[i + 1].f + 2) / 4; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void inverse_5x3_LeGall_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, ! +! ------------ uint64 res1) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function applies the inverse (5-3) LeGall wavelet transform on the data samples stored ! +! in the working buffer. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for the one dimensional dwt. ! +! ! +! res0 unsigned int(64 bit) - Starting point for the current resolu- ! +! tion and dimension. ! +! ! +! res1 unsigned int(64 bit) - End point for the current resolution ! +! and dimension. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +inverse_5x3_LeGall_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, uint64 res1) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, length; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(working_buffer); + + length = res1 - res0; + + /*--------------------------------------------------------*\ + ! Perform the update step on the even samples. ! + \*--------------------------------------------------------*/ + for(i = -2; i < length + 1; i += 2) + { + working_buffer[i].f -= (working_buffer[i - 1].f + working_buffer[i + 1].f + 2) / 4; + } + + /*--------------------------------------------------------*\ + ! Perform the predictor step on the odd samples. ! + \*--------------------------------------------------------*/ + for(i = -1; i < length; i += 2) + { + working_buffer[i].f += (working_buffer[i - 1].f + working_buffer[i + 1].f) / 2; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void forward_Haar_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, ! +! ------------ uint64 res1) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function applies the forward Haar wavelet transform on the data samples stored in the ! +! working buffer. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for the one dimensional dwt. ! +! ! +! res0 unsigned int(64 bit) - Starting point for the current resolu- ! +! tion and dimension. ! +! ! +! res1 unsigned int(64 bit) - End point for the current resolution ! +! and dimension. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +forward_Haar_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, uint64 res1) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, length; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(working_buffer); + + length = res1 - res0; + + /*--------------------------------------------------------*\ + ! Perform the predictor step on the odd samples. ! + \*--------------------------------------------------------*/ + for(i = 1; i < length; i += 2) + { + working_buffer[i].f -= working_buffer[i - 1].f; + } + + /*--------------------------------------------------------*\ + ! Perform the update step on the even samples. ! + \*--------------------------------------------------------*/ + for(i = 0; i < length; i += 2) + { + working_buffer[i].f += working_buffer[i + 1].f / 2; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void inverse_Haar_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, ! +! ------------ uint64 res1) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function applies the inverse Haar wavelet transform on the data samples stored in the ! +! working buffer. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for the one dimensional dwt. ! +! ! +! res0 unsigned int(64 bit) - Starting point for the current resolu- ! +! tion and dimension. ! +! ! +! res1 unsigned int(64 bit) - End point for the current resolution ! +! and dimension. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +inverse_Haar_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, uint64 res1) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, length; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(working_buffer); + + length = res1 - res0; + + /*--------------------------------------------------------*\ + ! Perform the update step on the even samples. ! + \*--------------------------------------------------------*/ + for(i = 0; i < length; i += 2) + { + working_buffer[i].f -= working_buffer[i + 1].f / 2; + } + + /*--------------------------------------------------------*\ + ! Perform the predictor step on the odd samples. ! + \*--------------------------------------------------------*/ + for(i = 1; i < length; i += 2) + { + working_buffer[i].f += working_buffer[i - 1].f; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void buffer_flush_forward(bwc_sample *const data, bwc_sample *const working_buffer, ! +! ------------ uint64 res0, ! +! uint64 res1, ! +! uint64 increment) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function creates the low- and highbands in the tile parameter after a one dimensional ! +! wavelet transform by copying the coefficients in the working buffer to their appropriate ! +! position in the tile parameter memory. In case of an odd length working buffer there are ! +! half_length + 1 lowband coefficients present in the buffer memory. Therefore, this func- ! +! tion loops through half_length - 1 wavelet coefficients and handles the last (two) coeffi- ! +! cient(s) separately. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for the one dimensional dwt. ! +! ! +! res0 unsigned int(64 bit) - Starting point for the current resolu- ! +! tion and dimension. ! +! ! +! res1 unsigned int(64 bit) - End point for the current resolution ! +! and dimension. ! +! ! +! increment unsigned int(64 bit) - Data increment for strided memory ac- ! +! cess. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +buffer_flush_forward(bwc_sample *const data, bwc_sample *const working_buffer, uint64 res0, uint64 res1, uint64 increment) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, length, half_length; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_sample *lowband, *highband; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(data); + assert(working_buffer); + + /*--------------------------------------------------------*\ + ! Calculate the length and half_length of the buffer. ! + \*--------------------------------------------------------*/ + length = res1 - res0; + half_length = (res0 % 2) ? length >> 1 : (length + 1) >> 1; + + /*--------------------------------------------------------*\ + ! Associate the data pointers to the starting point of the ! + ! low- and highband. ! + \*--------------------------------------------------------*/ + lowband = data; + highband = data + half_length * increment; + + /*--------------------------------------------------------*\ + ! In case of an odd starting point copy the first highband ! + ! coefficient from the working buffer. ! + \*--------------------------------------------------------*/ + if(res0 % 2) + { + highband->f = working_buffer[-1].f; + highband += increment; + } + + /*--------------------------------------------------------*\ + ! Loop over the interleaved values in the working buffer ! + ! and fill the high- and lowbands in the tile parameter ! + ! memory. ! + \*--------------------------------------------------------*/ + for(i = 0; i < half_length - 1; ++i) + { + lowband->f = working_buffer[i << 1].f; + highband->f = working_buffer[(i << 1) + 1].f; + lowband += increment; + highband += increment; + } + + /*--------------------------------------------------------*\ + ! Copy the remaining lowband coefficient in case of an odd ! + ! length working buffer. ! + \*--------------------------------------------------------*/ + if(res1 % 2) + { + lowband->f = working_buffer[i << 1].f; + } + + /*--------------------------------------------------------*\ + ! Copy the remaining high- and lowband coefficient in case ! + ! of an even length working buffer. ! + \*--------------------------------------------------------*/ + else + { + lowband->f = working_buffer[i << 1].f; + highband->f = working_buffer[(i << 1) + 1].f; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void buffer_flush_inverse(bwc_sample *const data, bwc_sample *const working_buffer, ! +! ------------ uint64 res0, ! +! uint64 res1, ! +! uint64 increment) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function copies the decompressed flow field data for the current resolution level from ! +! the working buffer to the tile parameter memory. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for the one dimensional dwt. ! +! ! +! res0 unsigned int(64 bit) - Starting point for the current resolu- ! +! tion and dimension. ! +! ! +! res1 unsigned int(64 bit) - End point for the current resolution ! +! and dimension. ! +! ! +! increment unsigned int(64 bit) - Data increment for strided memory ac- ! +! cess. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +buffer_flush_inverse(bwc_sample *const data, bwc_sample *const working_buffer, uint64 res0, uint64 res1, uint64 increment) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, j, length; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_sample *memory; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(data); + assert(working_buffer); + + /*--------------------------------------------------------*\ + ! Associate the data pointer to the starting point of the ! + ! tile parameter resolution. ! + \*--------------------------------------------------------*/ + memory = data; + + /*--------------------------------------------------------*\ + ! Calculate the length of the buffer. ! + \*--------------------------------------------------------*/ + length = res1 - res0; + + /*--------------------------------------------------------*\ + ! In case of an odd starting point copy the first sample ! + ! to the tile parameter memory. ! + \*--------------------------------------------------------*/ + if(res0 % 2) + { + memory->f = working_buffer[-1].f; + memory += increment; + length--; + } + + /*--------------------------------------------------------*\ + ! Copy the decompressed flow field data from the working ! + ! buffer to the strided tile parameter memory for the ! + ! current resolution level. ! + \*--------------------------------------------------------*/ + for(i = 0, j = 0; i < length; ++i) + { + memory[j].f = working_buffer[i].f; + j += increment; + } +} +/************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: int initialize_gain_lut() ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function calculates the energy gain factor Gb for the one dimensional, dyadic tree ! +! structured CDF-(9/7), LeGall-(5/3) and Haar wavelet transform with 5 levels. The energy ! +! gain factors are calculated according to equation (4.39) from JPEG2000 by David S. Taubman ! +! and Michael W. Marcellin (p. 193): ! +! ! +! s_L1[n] = g0[n], s_H1[n] = h0[n], ! +! s_Ld[n] = ∑(s_Ld-1[k]*g0[n-2k], k), s_Hd[n] = ∑(s_Hd-1[k]*g0[n-2k], k). ! +! ! +! The energy gain factors are stored in their corresponding lookup tables and used to calcu- ! +! late the energy gain for the multi dimensional wavelet transforms according to equation ! +! (4.40) from JPEG2000 by David S. Taubman and Michael W. Marcellin (p.193): ! +! ! +! s_LLD[n1,n2] = s_LD[n1] * s_LD[n2] => G_LLD = G_LD * G_LD ! +! s_HLD[n1,n2] = s_LD[n1] * s_HD[n2] => G_HLD = G_LD * G_HD ! +! s_LHD[n1,n2] = s_HD[n1] * s_LD[n2] => G_LHD = G_HD * G_LD ! +! s_HHD[n1,n2] = s_HD[n1] * s_HD[n2] => G_HHD = G_HD * G_HD ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Error flag used to determine wether the LUT initialization ! +! was successful. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 21.03.2017 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +initialize_gain_lut() +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int32 l,m; + int8 i,j,k; + int8 Length_FB, Length_Gb; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + double *buff1, *buff2, *temp; + double *LUT; + + /*-----------------------*\ + ! DEFINE INT CONSTANTS: ! + \*-----------------------*/ + static const int* Length; + static const int DWT_HAAR_FILTER_LENGTH[2] = {2,2}; + static const int DWT_5X3_FILTER_LENGTH[2] = {1,2}; + static const int DWT_9X7_FILTER_LENGTH[2] = {3,4}; + + /*-----------------------*\ + ! DEFINE FLOAT CONSTANTS: ! + \*-----------------------*/ + const double* filter_taps; + + static const double DWT_HAAR_FILTER[2][5] = {{DWT_HAAR_H1, DWT_HAAR_H0, 0, 0, 0}, + {DWT_HAAR_G1, DWT_HAAR_G0, 0, 0, 0}}; + static const double DWT_5X3_FILTER[2][5] = {{DWT_5X3_H1, DWT_5X3_H0, 0, 0, 0}, + {DWT_5X3_G2, DWT_5X3_G1, DWT_5X3_G0, 0, 0}}; + static const double DWT_9X7_FILTER[2][5] = {{DWT_9X7_H3, DWT_9X7_H2, DWT_9X7_H1, DWT_9X7_H0, 0}, + {DWT_9X7_G4, DWT_9X7_G3, DWT_9X7_G2, DWT_9X7_G1, DWT_9X7_G0}}; + + /*--------------------------------------------------------*\ + ! Allocate memory for the work buffers used to calculate ! + ! the energy gain factors. ! + \*--------------------------------------------------------*/ + buff1 = calloc(512, sizeof(double)); + buff2 = calloc(512, sizeof(double)); + if (!buff1 || !buff2) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(buff1); + free(buff2); + return 1; + } + + /*--------------------------------------------------------*\ + ! Initialize the lookup tables for the CDF-(9/7), LeGall- ! + ! (5/3) and Haar wavelet transform by setting the energy ! + ! gain factor for level zero to one. ! + \*--------------------------------------------------------*/ + DWT_ENERGY_GAIN_LUT[bwc_dwt_9_7][0] = DWT_ENERGY_GAIN_LUT[bwc_dwt_9_7][MAX_DECOMPOSITION_LEVELS + 1] = 1.0f; + DWT_ENERGY_GAIN_LUT[bwc_dwt_5_3][0] = DWT_ENERGY_GAIN_LUT[bwc_dwt_5_3][MAX_DECOMPOSITION_LEVELS + 1] = 1.0f; + DWT_ENERGY_GAIN_LUT[bwc_dwt_haar][0] = DWT_ENERGY_GAIN_LUT[bwc_dwt_haar][MAX_DECOMPOSITION_LEVELS + 1] = 1.0f; + + /*--------------------------------------------------------*\ + ! Loop through the symmetric wavelet filter banks and as- ! + ! semble their respective energy gain factor lookup table. ! + \*--------------------------------------------------------*/ + for(i = 0; i < 2; i++) + { + /*--------------------------------------------------------*\ + ! Assign the Lookup Table (LUT), Length and filter_taps ! + ! pointer to their respective wavelet kernel and set the ! + ! filter_bank (Length_FB) and work buffer (Length_Gb) ! + ! length to the corresponding low-pass synthesis filter ! + ! length. ! + \*--------------------------------------------------------*/ + if(i == 0) + { + LUT = &DWT_ENERGY_GAIN_LUT[bwc_dwt_9_7][1]; + Length = &DWT_9X7_FILTER_LENGTH[0]; + Length_FB = Length_Gb = Length[0]; + filter_taps = &DWT_9X7_FILTER[0][0]; + } + else if(i == 1) + { + LUT = &DWT_ENERGY_GAIN_LUT[bwc_dwt_5_3][1]; + Length = &DWT_5X3_FILTER_LENGTH[0]; + Length_FB = Length_Gb = Length[0]; + filter_taps = &DWT_5X3_FILTER[0][0]; + } + /*--------------------------------------------------------*\ + ! Loop through the low- and high-pass synthesis filter ! + ! banks of the corresponding wavelet kernel. ! + \*--------------------------------------------------------*/ + for(j = 0; j < 2; j++) + { + /*--------------------------------------------------------*\ + ! Initialize work buffer 1 with the low-pass filter for ! + ! the low-pass energy gain factor, or the high-pass filter ! + ! for the high-pass energy gain factor. ! + \*--------------------------------------------------------*/ + for(k = 0; k < Length_Gb + 1; ++k) + { + buff1[k] = buff1[2*Length_Gb-k] = filter_taps[k+5*j]; + } + /*--------------------------------------------------------*\ + ! Calculate the energy gain factor for the first decomp. ! + ! level by evaluating the square norm of work buffer 1. ! + \*--------------------------------------------------------*/ + for(k = 0; k < (2 * Length_Gb + 1); ++k) + { + LUT[0] += buff1[k] * buff1[k]; + } + /*--------------------------------------------------------*\ + ! Loop through the remaining decomposition levels. ! + \*--------------------------------------------------------*/ + for(k = 1; k < MAX_DECOMPOSITION_LEVELS; ++k) + { + /*--------------------------------------------------------*\ + ! Assemble the low- or high-pass synthesis sequence for ! + ! decomposition level i in work buffer 2. ! + \*--------------------------------------------------------*/ + for(l = 0; l < (2 * Length_Gb + 1); ++l) + { + buff2[2 * l + Length_FB] += buff1[l] * filter_taps[Length_FB]; + for(m = 0; m < Length_FB; ++m) + { + buff2[2 * l + m] += buff1[l] * filter_taps[m]; + buff2[2 * l + (2*Length_FB-m)] += buff1[l] * filter_taps[m]; + } + } + /*--------------------------------------------------------*\ + ! Assign the memory of work buffer 2 to work buffer 1 and ! + ! vice versa. Set work buffer 2 to 0 and reevaluate the ! + ! length of work buffer 1. ! + \*--------------------------------------------------------*/ + temp = buff1; + buff1 = buff2; + buff2 = temp; + memset(buff2, 0, 512 * sizeof(double)); + Length_Gb = 2* Length_Gb + Length_FB; + /*--------------------------------------------------------*\ + ! Calculate the energy gain factor for decomposition level ! + ! i by evaluating the square norm of work buffer 1. ! + \*--------------------------------------------------------*/ + for(l = 0; l < (2 * Length_Gb + 1); ++l) + { + LUT[k] += buff1[l] * buff1[l]; + } + } + /*--------------------------------------------------------*\ + ! Advance the LUT Pointer to the memory reserved for the ! + ! high-pass energy gain factor and set the length of work ! + ! buffer 1 to the corresponding high-pass filter length. ! + \*--------------------------------------------------------*/ + LUT += MAX_DECOMPOSITION_LEVELS + 1; + Length_Gb = Length[1]; + } + /*--------------------------------------------------------*\ + ! Set work buffer 1 to 0. ! + \*--------------------------------------------------------*/ + memset(buff1, 0, 512 * sizeof(double)); + } + + /*--------------------------------------------------------*\ + ! Loop through the asymmetric wavelet filter banks and as- ! + ! semble their respective energy gain factor lookup table. ! + \*--------------------------------------------------------*/ + for(i = 0; i < 1; ++i) + { + /*--------------------------------------------------------*\ + ! Initialize work buffer 1 with the low-pass filter for ! + ! the low-pass energy gain factor, or the high-pass filter ! + ! for the high-pass energy gain factor. ! + \*--------------------------------------------------------*/ + if(i == 0) + { + LUT = &DWT_ENERGY_GAIN_LUT[bwc_dwt_haar][1]; + Length = &DWT_HAAR_FILTER_LENGTH[0]; + Length_FB = Length_Gb = Length[0]; + filter_taps = &DWT_HAAR_FILTER[0][0]; + } + /*--------------------------------------------------------*\ + ! Loop through the low- and high-pass synthesis filter ! + ! banks of the corresponding wavelet kernel. ! + \*--------------------------------------------------------*/ + for(j = 0; j < 2; ++j) + { + /*--------------------------------------------------------*\ + ! Initialize work buffer 1 with the low-pass filter for ! + ! the low-pass energy gain factor, or the high-pass filter ! + ! for the high-pass energy gain factor. ! + \*--------------------------------------------------------*/ + for(k = 0; k < Length_Gb; ++k) + { + buff1[k] = filter_taps[k+5*j]; + } + /*--------------------------------------------------------*\ + ! Calculate the energy gain factor for the first decomp. ! + ! level by evaluating the square norm of work buffer 1. ! + \*--------------------------------------------------------*/ + for(k = 0; k < Length_Gb; ++k) + { + LUT[0] += buff1[k] * buff1[k]; + } + /*--------------------------------------------------------*\ + ! Loop through the remaining decomposition levels. ! + \*--------------------------------------------------------*/ + for(k = 1; k < MAX_DECOMPOSITION_LEVELS; ++k) + { + /*--------------------------------------------------------*\ + ! Assemble the low- or high-pass synthesis sequence for ! + ! decomposition level i in work buffer 2. ! + \*--------------------------------------------------------*/ + for(l = 0; l < Length_Gb; ++l) + { + for(m = 0; m < Length_FB; m++) + { + buff2[2 * l + m] += buff1[l] * filter_taps[m]; + } + } + /*--------------------------------------------------------*\ + ! Assign the memory of work buffer 2 to work buffer 1 and ! + ! vice versa. Set work buffer 2 to 0 and reevaluate the ! + ! length of work buffer 1. ! + \*--------------------------------------------------------*/ + temp = buff1; + buff1 = buff2; + buff2 = temp; + memset(buff2, 0, 512 * sizeof(double)); + Length_Gb = Length_Gb * Length_FB; + /*--------------------------------------------------------*\ + ! Calculate the energy gain factor for decomposition level ! + ! i by evaluating the square norm of work buffer 1. ! + \*--------------------------------------------------------*/ + for(l = 0; l < Length_Gb; ++l) + { + LUT[k] += buff1[l] * buff1[l]; + } + } + /*--------------------------------------------------------*\ + ! Calculate the energy gain factor for decomposition level ! + ! i by evaluating the square norm of work buffer 1. ! + \*--------------------------------------------------------*/ + LUT += MAX_DECOMPOSITION_LEVELS + 1; + Length_Gb = Length[1]; + } + /*--------------------------------------------------------*\ + ! Set work buffer 1 to 0. ! + \*--------------------------------------------------------*/ + memset(buff1, 0, 512 * sizeof(double)); + } + /*--------------------------------------------------------*\ + ! Free work buffer 1 and 2 and exit the subroutine. ! + \*--------------------------------------------------------*/ + free(buff1); + free(buff2); + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: bwc_float get_dwt_energy_gain(bwc_field *const field, uchar highband_flag, uint16 level) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function evaluates the energy gain factor according to the the specified decomposition ! +! level. For decomposition levels larger than MAX_DECOMPOSITION_LEVELS the filter gain for ! +! the extra levels is approximated by multiplying the energy gain factor by 2. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! highband_flag uchar - Defines the subband for which Gb is ! +! calculated. ! +! ! +! level uint16 - Defines the decomposition level for ! +! which Gb is calculated ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! double - Energy gain factor for two dimensional tree-structured subband ! +! transforms. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 13.04.2017 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +bwc_float +get_dwt_energy_gain(bwc_field *const field, uchar highband_flag, uint16 level) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int8 level_X, level_Y, level_Z; + int8 level_TS; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + double Gb = 1.0f; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(level <= field->control.nDecomp + 1); + assert(highband_flag <= DIM_ALL); + + /*--------------------------------------------------------*\ + ! Save the global control structure to a temporary varia- ! + ! ble to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Evaluate the number of decompositions in each temporal & ! + ! spatial directions according to the the global decompo - ! + ! sition level for which the energy gain factor is calcu- ! + ! lated for. ! + \*--------------------------------------------------------*/ + level_X = (level > control->decompX ) ? control->decompX : level; + level_Y = (level > control->decompY ) ? control->decompY : level; + level_Z = (level > control->decompZ ) ? control->decompZ : level; + level_TS = (level > control->decompTS) ? control->decompTS : level; + + /*--------------------------------------------------------*\ + ! Multiply the energy gain factor with the filter gain of ! + ! the wavelet kernel applied along the X-axis. For decom- ! + ! position levels larger than MAX_DECOMPOSITION_LEVELS the ! + ! energy gain for the extra levels is approximated by mul- ! + ! tiplying it by 2. ! + \*--------------------------------------------------------*/ + if(level_X != 0) + { + while(level_X > MAX_DECOMPOSITION_LEVELS) + { + Gb *= 2.0f; + level_X--; + } + + Gb *= DWT_ENERGY_GAIN_LUT[control->KernelX][level_X + ((highband_flag & DIM_X) * (MAX_DECOMPOSITION_LEVELS + 1))]; + } + + /*--------------------------------------------------------*\ + ! Multiply the energy gain factor with the filter gain of ! + ! the wavelet kernel applied along the Y-axis. For decom- ! + ! position levels larger than MAX_DECOMPOSITION_LEVELS the ! + ! energy gain for the extra levels is approximated by mul- ! + ! tiplying it by 2. ! + \*--------------------------------------------------------*/ + if(level_Y != 0) + { + while(level_Y > MAX_DECOMPOSITION_LEVELS) + { + Gb *= 2.0f; + level_Y--; + } + + Gb *= DWT_ENERGY_GAIN_LUT[control->KernelY][level_Y + (((highband_flag & DIM_Y) >> 1) * (MAX_DECOMPOSITION_LEVELS + 1))]; + } + + /*--------------------------------------------------------*\ + ! Multiply the energy gain factor with the filter gain of ! + ! the wavelet kernel applied along the Z-axis. For decom- ! + ! position levels larger than MAX_DECOMPOSITION_LEVELS the ! + ! energy gain for the extra levels is approximated by mul- ! + ! tiplying it by 2. ! + \*--------------------------------------------------------*/ + if(level_Z != 0) + { + while(level_Z > MAX_DECOMPOSITION_LEVELS) + { + Gb *= 2.0f; + level_Z--; + } + + Gb *= DWT_ENERGY_GAIN_LUT[control->KernelZ][level_Z + (((highband_flag & DIM_Z) >> 2) * (MAX_DECOMPOSITION_LEVELS + 1))]; + } + + /*--------------------------------------------------------*\ + ! Multiply the energy gain factor with the filter gain of ! + ! the wavelet kernel applied along the TS-axis. For decom- ! + ! position levels larger than MAX_DECOMPOSITION_LEVELS the ! + ! energy gain for the extra levels is approximated by mul- ! + ! tiplying it by 2. ! + \*--------------------------------------------------------*/ + if(level_TS != 0) + { + while(level_TS > MAX_DECOMPOSITION_LEVELS) + { + Gb *= 2.0f; + level_TS--; + } + + Gb *= DWT_ENERGY_GAIN_LUT[control->KernelTS][level_TS + (((highband_flag & DIM_TS) >> 3) * (MAX_DECOMPOSITION_LEVELS + 1))]; + } + return (bwc_float)Gb; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar forward_discrete_wavelet_transform(bwc_field *const field, ! +! -------------- bwc_parameter *const parameter) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function performs the forward discrete wavelet transform on the current tile param- ! +! eter. After loading the flow field samples for a row, column or spatial/temporal slice ! +! into a working buffer, a boundary extension operation is performed to ensure an approp. ! +! sample base. The working buffer is then transform using the wavelet kernel selected for ! +! the spatial or temporal dimension, sorted into high- and low-frequency samples and flushed ! +! back into the tile parameter memory block. This operation is performed for every row, ! +! column and spatial/temporal slice for nDecomp number of decomposition levels. ! +! ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! parameter bwc_parameter* - Structure defining a bwc parameter. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 13.04.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +forward_discrete_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 incr_X, incr_Y, incr_Z; + uint64 rX0, rY0, rZ0; + uint64 rX1, rY1, rZ1; + uint64 width, height, depth; + uint64 x, y, z; + uint32 buff_size; + int16 i; + uint16 incr_TS; + uint16 rTS0; + uint16 rTS1; + uint16 dt; + uint16 t; + uint8 id; + uint8 filter_tapsX, filter_tapsY, filter_tapsZ; + uint8 filter_tapsTS; + uint8 level; + uint8 nThreads; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_param_inf *param_info; + bwc_sample *data, *working_buffer; + bwc_sample **memory; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(parameter); + + /*-----------------------*\ + ! DEFINE FUNCTION PTR: ! + \*-----------------------*/ + void (*forward_wavelet_transform[3])(bwc_sample*, uint64, uint64) = {forward_9x7_CDF_wavelet_transform, + forward_5x3_LeGall_wavelet_transform, + forward_Haar_wavelet_transform}; + + void (*boundary_extension[3])(bwc_sample *, uint64, uint64, uint8) = {whole_point_symmetric_extend, + whole_point_symmetric_extend, + NULL}; + + /*--------------------------------------------------------*\ + ! Save the global control and parameter info structure to ! + ! temporary variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + param_info = ¶meter->info; + + /*--------------------------------------------------------*\ + ! Calculate the width, height, depth and temporal size dt ! + ! of the current tile parameter. ! + \*--------------------------------------------------------*/ + width = param_info->X1 - param_info->X0; + height = param_info->Y1 - param_info->Y0; + depth = param_info->Z1 - param_info->Z0; + dt = param_info->TS1 - param_info->TS0; + + /*--------------------------------------------------------*\ + ! Calculate the increments used to fill the working buffer ! + ! for the spacial/temporal wavelet transformation. ! + \*--------------------------------------------------------*/ + incr_X = 1; + incr_Y = width; + incr_Z = width * height; + incr_TS = width * height * depth; + + /*--------------------------------------------------------*\ + ! Evaluate the filter taps for the spatial and temporal ! + ! wavelet filters. Additionally, the filter taps are in- ! + ! creased by 2 to account for an increase in highband ! + ! coefficients in case of an odd-length dataset. ! + \*--------------------------------------------------------*/ + filter_tapsX = get_filter_taps(control->KernelX) + 2; + filter_tapsY = get_filter_taps(control->KernelY) + 2; + filter_tapsZ = get_filter_taps(control->KernelZ) + 2; + filter_tapsTS = get_filter_taps(control->KernelTS) + 2; + + /*--------------------------------------------------------*\ + ! Evaluate the number of threads for the current compres- ! + ! sion run and the buffer size for the current tile param- ! + ! eter. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + nThreads = control->nThreads; + #else + nThreads = 1; + #endif + + buff_size = MAX(MAX(width, height), MAX(depth, dt)) + 2 * + MAX(MAX(filter_tapsX, filter_tapsY), + MAX(filter_tapsZ, filter_tapsTS)); + + /*--------------------------------------------------------*\ + ! Allocate the memory array and memory blocks for the ! + ! working buffer for each OpenMP thread. In case of a ! + ! serial run only one memory block will be allocated. ! + \*--------------------------------------------------------*/ + memory = calloc(nThreads, sizeof(bwc_sample*)); + if(!memory) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + for(i = 0; i < nThreads; ++i) + { + memory[i] = calloc(buff_size, sizeof(bwc_sample)); + if(!memory[i]) + { + // memory allocation error + fprintf(stderr, MEMERROR); + for(i--; i > 0; --i) + { + free(memory[i]); + } + free(memory); + return 1; + } + } + + /*--------------------------------------------------------*\ + ! Walk through all decomposition levels and apply the 1D ! + ! wavelet transform along the spatial and temporal dimen- ! + ! sions specified in the control structure. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp parallel private(data, id, level, working_buffer, rX0, rX1, rY0, rY1, rZ0, rZ1, rTS0, rTS1) + #endif + { + /*--------------------------------------------------------*\ + ! Evaluate the id of the current OpenMP thread. In case of ! + ! a serial run the thread id is set to 0. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + id = omp_get_thread_num(); + #else + id = 0; + #endif + + for(level = 0; level < control->nDecomp; ++level) + { + /*--------------------------------------------------------*\ + ! Save the resolution starting and end points to a tempo- ! + ! rary variable to make the code more readable. ! + \*--------------------------------------------------------*/ + rX0 = (uint64)parameter->resolution[control->nDecomp - level].info.X0; + rX1 = (uint64)parameter->resolution[control->nDecomp - level].info.X1; + rY0 = (uint64)parameter->resolution[control->nDecomp - level].info.Y0; + rY1 = (uint64)parameter->resolution[control->nDecomp - level].info.Y1; + rZ0 = (uint64)parameter->resolution[control->nDecomp - level].info.Z0; + rZ1 = (uint64)parameter->resolution[control->nDecomp - level].info.Z1; + rTS0 = (uint16)parameter->resolution[control->nDecomp - level].info.TS0; + rTS1 = (uint16)parameter->resolution[control->nDecomp - level].info.TS1; + + if(level < control->decompX && (rX1 - rX0) > 1) + { + /*--------------------------------------------------------*\ + ! Associate the working buffer pointer to the allocated ! + ! memory block. The working buffer points to the appropri- ! + ! ate starting point in the memory block, accounting for ! + ! the taps of the wavelet kernel selected for the first ! + ! spatial dimension. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsX]; + + /*--------------------------------------------------------*\ + ! Adjust the working buffer pointer in case of an odd ! + ! length column starting point. ! + \*--------------------------------------------------------*/ + if(rX0 % 2) + { + ++working_buffer; + } + + /*--------------------------------------------------------*\ + ! Walk trough all the temporal and spatial slices as well ! + ! as rows. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp for collapse(3) + #endif + for(t = 0; t < (rTS1 - rTS0); ++t) + { + for(z = 0; z < (rZ1 - rZ0); ++z) + { + for(y = 0; y < (rY1 - rY0); ++y) + { + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next column. ! + \*--------------------------------------------------------*/ + data = parameter->data + y * incr_Y + z * incr_Z + t * incr_TS; + + /*--------------------------------------------------------*\ + ! In the event that the current column and resolution only ! + ! encompasses 1 value, the sample will remain unaltered. ! + ! In case of an odd starting point the sample will be ! + ! doubled. ! + \*--------------------------------------------------------*/ + if((rX1 - rX0) == 1) + { + if(rX0 & 2) + { + data[0].f *= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the y-th tile parameter ! + ! column. ! + \*--------------------------------------------------------*/ + fill_forward_buffer(data, &memory[id][filter_tapsX], rX0, rX1, incr_X); + + /*--------------------------------------------------------*\ + ! Apply the boundary extension on the working buffer ap- ! + ! propriate to the specified wavelet kernel. ! + \*--------------------------------------------------------*/ + boundary_extension[control->KernelX](&memory[id][filter_tapsX], rX0, rX1, filter_tapsX); + + /*--------------------------------------------------------*\ + ! Perform the forward wavelet transform on the current ! + ! column. ! + \*--------------------------------------------------------*/ + forward_wavelet_transform[control->KernelX](working_buffer, rX0, rX1); + + /*--------------------------------------------------------*\ + ! Copy the interleaved wavelet coefficients from the work- ! + ! ing buffer to the tile parameter memory. ! + \*--------------------------------------------------------*/ + buffer_flush_forward(data, working_buffer, rX0, rX1, incr_X); + } + } + } + } + + if(level < control->decompY && (rY1 - rY0) > 1) + { + /*--------------------------------------------------------*\ + ! Associate the working buffer pointer to the allocated ! + ! memory block. The working buffer points to the appropri- ! + ! ate starting point in the memory block, accounting for ! + ! for the taps of the wavelet kernel selected for the ! + ! second spatial dimension. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsY]; + + /*--------------------------------------------------------*\ + ! Adjust the working buffer pointer in case of an odd ! + ! length row starting point. ! + \*--------------------------------------------------------*/ + if(rY0 % 2) + { + working_buffer++; + } + + /*--------------------------------------------------------*\ + ! Walk trough all the temporal and spatial slices as well ! + ! as columns. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp for collapse(3) + #endif + for(t = 0; t < (rTS1 - rTS0); ++t) + { + for(z = 0; z < (rZ1 - rZ0); ++z) + { + for(x = 0; x < (rX1 - rX0); ++x) + { + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next row. ! + \*--------------------------------------------------------*/ + data = parameter->data + x * incr_X + z * incr_Z + t * incr_TS; + + /*--------------------------------------------------------*\ + ! In the event that the current row and resolution only ! + ! encompasses 1 value, the sample will remain unaltered. ! + ! In case of an odd starting point the sample will be ! + ! doubled. ! + \*--------------------------------------------------------*/ + if((rY1 - rY0) == 1) + { + if(rY0 & 2) + { + data[0].f *= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the x-th tile parameter ! + ! row. ! + \*--------------------------------------------------------*/ + fill_forward_buffer(data, &memory[id][filter_tapsY], rY0, rY1, incr_Y); + + /*--------------------------------------------------------*\ + ! Apply the boundary extension on the working buffer ap- ! + ! propriate to the specified wavelet kernel. ! + \*--------------------------------------------------------*/ + boundary_extension[control->KernelY](&memory[id][filter_tapsY], rY0, rY1, filter_tapsY); + + /*--------------------------------------------------------*\ + ! Perform the forward wavelet transform on the current ! + ! row. ! + \*--------------------------------------------------------*/ + forward_wavelet_transform[control->KernelY](working_buffer, rY0, rY1); + + /*--------------------------------------------------------*\ + ! Copy the interleaved wavelet coefficients from the work- ! + ! ing buffer to the tile parameter memory. ! + \*--------------------------------------------------------*/ + buffer_flush_forward(data, working_buffer, rY0, rY1, incr_Y); + } + } + } + } + + if(level < control->decompZ && (rZ1 - rZ0) > 1) + { + /*--------------------------------------------------------*\ + ! Associate the working buffer pointer to the allocated ! + ! memory block. The working buffer points to the appropri- ! + ! ate starting point in the memory block, accounting for ! + ! for the taps of the wavelet kernel selected for the ! + ! third spatial dimension. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsZ]; + + /*--------------------------------------------------------*\ + ! Adjust the working buffer pointer in case of an odd ! + ! length starting point of the spatial slice. ! + \*--------------------------------------------------------*/ + if(rZ0 % 2) + { + working_buffer++; + } + + /*--------------------------------------------------------*\ + ! Walk trough all the temporal slices, rows and columns. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp for collapse(3) + #endif + for(t = 0; t < (rTS1 - rTS0); ++t) + { + for(y = 0; y < (rY1 - rY0); ++y) + { + for(x = 0; x < (rX1 - rX0); ++x) + { + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next spatial slice. ! + \*--------------------------------------------------------*/ + data = parameter->data + x * incr_X + y * incr_Y + t * incr_TS; + + /*--------------------------------------------------------*\ + ! In the event that the current slice and resolution only ! + ! encompasses 1 value, the sample will remain unaltered. ! + ! In case of an odd starting point the sample will be ! + ! doubled. ! + \*--------------------------------------------------------*/ + if((rZ1 - rZ0) == 1) + { + if(rZ0 & 2) + { + data[0].f *= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the x-th spatial tile para- ! + ! meter slice. ! + \*--------------------------------------------------------*/ + fill_forward_buffer(data, &memory[id][filter_tapsZ], rZ0, rZ1, incr_Z); + + /*--------------------------------------------------------*\ + ! Apply the boundary extension on the working buffer ap- ! + ! propriate to the specified wavelet kernel. ! + \*--------------------------------------------------------*/ + boundary_extension[control->KernelZ](&memory[id][filter_tapsZ], rZ0, rZ1, filter_tapsZ); + + /*--------------------------------------------------------*\ + ! Perform the forward wavelet transform on the current ! + ! spatial slice. ! + \*--------------------------------------------------------*/ + forward_wavelet_transform[control->KernelZ](working_buffer, rZ0, rZ1); + + /*--------------------------------------------------------*\ + ! Copy the interleaved wavelet coefficients from the work- ! + ! ing buffer to the tile parameter memory. ! + \*--------------------------------------------------------*/ + buffer_flush_forward(data, working_buffer, rZ0, rZ1, incr_Z); + } + } + } + } + + if(level < control->decompTS && (rTS1 - rTS0) > 1) + { + /*--------------------------------------------------------*\ + ! Associate the working buffer pointer to the allocated ! + ! memory block. The working buffer points to the appropri- ! + ! ate starting point in the memory block, accounting for ! + ! for the taps of the wavelet kernel selected for the ! + ! temporal dimension. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsTS]; + + /*--------------------------------------------------------*\ + ! Adjust the working buffer pointer in case of an odd ! + ! length starting point of the temporal slice. ! + \*--------------------------------------------------------*/ + if(rTS0 % 2) + { + working_buffer++; + } + + /*--------------------------------------------------------*\ + ! Walk trough all the spatial slices, rows and columns. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp for collapse(3) + #endif + for(z = 0; z < (rZ1 - rZ0); ++z) + { + for(y = 0; y < (rY1 - rY0); ++y) + { + for(x = 0; x < (rX1 - rX0); ++x) + { + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next temporal slice. ! + \*--------------------------------------------------------*/ + data = parameter->data + x * incr_X + y * incr_Y + z * incr_Z; + + /*--------------------------------------------------------*\ + ! In the event that the current slice and resolution only ! + ! encompasses 1 value, the sample will remain unaltered. ! + ! In case of an odd starting point the sample will be ! + ! doubled. ! + \*--------------------------------------------------------*/ + if((rTS1 - rTS0) == 1) + { + if(rTS0 & 2) + { + data[0].f *= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the x-th temporal tile para-! + ! meter slice. ! + \*--------------------------------------------------------*/ + fill_forward_buffer(data, &memory[id][filter_tapsTS], rTS0, rTS1, incr_TS); + + /*--------------------------------------------------------*\ + ! Apply the boundary extension on the working buffer ap- ! + ! propriate to the specified wavelet kernel. ! + \*--------------------------------------------------------*/ + boundary_extension[control->KernelTS](&memory[id][filter_tapsTS], rTS0, rTS1, filter_tapsTS); + + /*--------------------------------------------------------*\ + ! Perform the forward wavelet transform on the current ! + ! temporal slice. ! + \*--------------------------------------------------------*/ + forward_wavelet_transform[control->KernelTS](working_buffer, rTS0, rTS1); + + /*--------------------------------------------------------*\ + ! Copy the interleaved wavelet coefficients from the work- ! + ! ing buffer to the tile parameter memory. ! + \*--------------------------------------------------------*/ + buffer_flush_forward(data, working_buffer, rTS0, rTS1, incr_TS); + } + } + } + } + } + } + + /*--------------------------------------------------------*\ + ! Deallocate the memory array and memory blocks. ! + \*--------------------------------------------------------*/ + for(i = 0; i < nThreads; ++i) + { + free(memory[i]); + } + free(memory); + + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar inverse_discrete_wavelet_transform(bwc_field *const field, ! +! -------------- bwc_parameter *const parameter) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function performs the inverse discrete wavelet transform on the current tile param- ! +! eter. After loading the interweaved wavelet coefficients for a row, column or spatial/ ! +! temporal slice into a working buffer, a boundary extension operation is performed to ! +! ensure an appropriate sample base. The working buffer is then transform using the wave- ! +! let kernel selected for the spatial or temporal dimension and flushed back into the tile ! +! parameter memory block. This operation is performed for every row, column and spatial/ ! +! temporal slice for nDecomp number of decomposition levels. ! +! ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! parameter bwc_parameter* - Structure defining a bwc parameter. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 13.04.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +inverse_discrete_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 incr_X, incr_Y, incr_Z; + uint64 rX0, rY0, rZ0; + uint64 rX1, rY1, rZ1; + uint64 width, height, depth; + uint64 x, y, z; + uint32 buff_size; + int16 i; + uint16 incr_TS; + uint16 rTS0; + uint16 rTS1; + uint16 dt; + uint16 t; + uint8 id; + uint8 filter_tapsX, filter_tapsY, filter_tapsZ; + uint8 filter_tapsTS; + uint8 level; + uint8 nThreads; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_param_inf *param_info; + bwc_sample *data, *working_buffer; + bwc_sample **memory; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(parameter); + + /*-----------------------*\ + ! DEFINE FUNCTION PTR: ! + \*-----------------------*/ + void (*inverse_wavelet_transform[3])(bwc_sample*, uint64, uint64) = {inverse_9x7_CDF_wavelet_transform, + inverse_5x3_LeGall_wavelet_transform, + inverse_Haar_wavelet_transform}; + + void (*boundary_extension[3])(bwc_sample *, uint64, uint64, uint8) = {whole_point_symmetric_extend, + whole_point_symmetric_extend, + NULL}; + + /*--------------------------------------------------------*\ + ! Save the global control and parameter info structure to ! + ! temporary variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + param_info = ¶meter->info; + + /*--------------------------------------------------------*\ + ! Calculate the width, height, depth and temporal size dt ! + ! of the current tile parameter. ! + \*--------------------------------------------------------*/ + width = param_info->X1 - param_info->X0; + height = param_info->Y1 - param_info->Y0; + depth = param_info->Z1 - param_info->Z0; + dt = param_info->TS1 - param_info->TS0; + + /*--------------------------------------------------------*\ + ! Calculate the increments used to fill the working buffer ! + ! for the spacial/temporal wavelet transforms. ! + \*--------------------------------------------------------*/ + incr_X = 1; + incr_Y = width; + incr_Z = width * height; + incr_TS = width * height * depth; + + /*--------------------------------------------------------*\ + ! Evaluate the filter taps for the spatial and temporal ! + ! wavelet filters. Additionally, the filter taps are in- ! + ! creased by 2 to account for an increase in highband ! + ! coefficients in case of an odd-length dataset. ! + \*--------------------------------------------------------*/ + filter_tapsX = get_filter_taps(control->KernelX) + 2; + filter_tapsY = get_filter_taps(control->KernelY) + 2; + filter_tapsZ = get_filter_taps(control->KernelZ) + 2; + filter_tapsTS = get_filter_taps(control->KernelTS) + 2; + + /*--------------------------------------------------------*\ + ! Evaluate the number of threads for the current compres- ! + ! sion run and the buffer size for the current tile param- ! + ! eter. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + nThreads = control->nThreads; + #else + nThreads = 1; + #endif + + buff_size = MAX(MAX(width, height), MAX(depth, dt)) + 2 * + MAX(MAX(filter_tapsX, filter_tapsY), + MAX(filter_tapsZ, filter_tapsTS)); + + /*--------------------------------------------------------*\ + ! Allocate the memory array and memory blocks for the ! + ! working buffer of each OpenMP thread. In case of a ! + ! serial run only one memory block will be allocated. ! + \*--------------------------------------------------------*/ + memory = calloc(nThreads, sizeof(bwc_sample*)); + if(!memory) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + for(i = 0; i < nThreads; ++i) + { + memory[i] = calloc(buff_size, sizeof(bwc_sample)); + if(!memory[i]) + { + // memory allocation error + fprintf(stderr, MEMERROR); + for(i--; i > 0; --i) + { + free(memory[i]); + } + free(memory); + return 1; + } + } + + /*--------------------------------------------------------*\ + ! Walk through all decomposition levels and apply the 1D ! + ! wavelet transform along the spatial and temporal dimen- ! + ! sions specified in the control structure. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp parallel private(data, id, level, working_buffer, rX0, rX1, rY0, rY1, rZ0, rZ1, rTS0, rTS1) + #endif + { + /*--------------------------------------------------------*\ + ! Evaluate the id of the current OpenMP thread. In case of ! + ! a serial run the thread id is set to 1. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + id = omp_get_thread_num(); + #else + id = 0; + #endif + + for(level = control->nDecomp; level --> 0;) + { + /*--------------------------------------------------------*\ + ! Save the resolution starting and end points to a tempo- ! + ! rary variable to make the code more readable. ! + \*--------------------------------------------------------*/ + rX0 = (uint64)parameter->resolution[control->nDecomp - level].info.X0; + rX1 = (uint64)parameter->resolution[control->nDecomp - level].info.X1; + rY0 = (uint64)parameter->resolution[control->nDecomp - level].info.Y0; + rY1 = (uint64)parameter->resolution[control->nDecomp - level].info.Y1; + rZ0 = (uint64)parameter->resolution[control->nDecomp - level].info.Z0; + rZ1 = (uint64)parameter->resolution[control->nDecomp - level].info.Z1; + rTS0 = (uint16)parameter->resolution[control->nDecomp - level].info.TS0; + rTS1 = (uint16)parameter->resolution[control->nDecomp - level].info.TS1; + + if(level < control->decompTS && (rTS1 - rTS0) > 1) + { + /*--------------------------------------------------------*\ + ! Associate the working buffer pointer to the allocated ! + ! memory block. The working buffer points to the appropri- ! + ! ate starting point in the memory block, accounting for ! + ! the taps of the wavelet kernel selected for the temporal ! + ! dimension. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsTS]; + + /*--------------------------------------------------------*\ + ! Adjust the working buffer pointer in case of an odd ! + ! length starting point of the temporal slice. ! + \*--------------------------------------------------------*/ + if(rTS0 % 2) + { + working_buffer++; + } + + /*--------------------------------------------------------*\ + ! Walk trough all the spatial slices, rows and columns. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp for collapse(3) + #endif + for(z = 0; z < (rZ1 - rZ0); ++z) + { + for(y = 0; y < (rY1 - rY0); ++y) + { + for(x = 0; x < (rX1 - rX0); ++x) + { + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next temporal slice. ! + \*--------------------------------------------------------*/ + data = parameter->data + x * incr_X + y * incr_Y + z * incr_Z; + + /*--------------------------------------------------------*\ + ! In the event that the current slice and resolution only ! + ! encompasses 1 value, the sample will remain unaltered. ! + ! In case of an odd starting point the sample will be ! + ! doubled. ! + \*--------------------------------------------------------*/ + if((rTS1 - rTS0) == 1) + { + if(rTS0 & 2) + { + data[0].f *= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the x-th temporal tile para-! + ! meter slice. ! + \*--------------------------------------------------------*/ + fill_inverse_buffer(data, &memory[id][filter_tapsTS], rTS0, rTS1, incr_TS); + + /*--------------------------------------------------------*\ + ! Apply the boundary extension on the working buffer ap- ! + ! propriate to the specified wavelet kernel. ! + \*--------------------------------------------------------*/ + boundary_extension[control->KernelTS](&memory[id][filter_tapsTS], rTS0, rTS1, filter_tapsTS); + + /*--------------------------------------------------------*\ + ! Perform the inverse wavelet transform on the current ! + ! temporal slice. ! + \*--------------------------------------------------------*/ + inverse_wavelet_transform[control->KernelTS](working_buffer, rTS0, rTS1); + + /*--------------------------------------------------------*\ + ! Copy the interleaved wavelet coefficients from the work- ! + ! ing buffer to the tile parameter memory. ! + \*--------------------------------------------------------*/ + buffer_flush_inverse(data, working_buffer, rTS0, rTS1, incr_TS); + } + } + } + } + + if(level < control->decompZ && (rZ1 - rZ0) > 1) + { + /*--------------------------------------------------------*\ + ! Associate the working buffer pointer to the allocated ! + ! memory block. The working buffer points to the appropri- ! + ! ate starting point in the memory block, accounting for ! + ! for the taps of the wavelet kernel selected for the ! + ! third spatial dimension. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsZ]; + + /*--------------------------------------------------------*\ + ! Adjust the working buffer pointer in case of an odd ! + ! length starting point of the spatial slice. ! + \*--------------------------------------------------------*/ + if(rZ0 % 2) + { + working_buffer++; + } + + /*--------------------------------------------------------*\ + ! Walk trough all the temporal slices, rows and columns. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp for collapse(3) + #endif + for(t = 0; t < (rTS1 - rTS0); ++t) + { + for(y = 0; y < (rY1 - rY0); ++y) + { + for(x = 0; x < (rX1 - rX0); ++x) + { + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next spatial slice. ! + \*--------------------------------------------------------*/ + data = parameter->data + x * incr_X + y * incr_Y + t * incr_TS; + + /*--------------------------------------------------------*\ + ! In the event that the current slice and resolution only ! + ! encompasses 1 value, the sample will remain unaltered. ! + ! In case of an odd starting point the sample will be ! + ! doubled. ! + \*--------------------------------------------------------*/ + if((rZ1 - rZ0) == 1) + { + if(rZ0 & 2) + { + data[0].f /= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the x-th spatial tile para- ! + ! meter slice. ! + \*--------------------------------------------------------*/ + fill_inverse_buffer(data, &memory[id][filter_tapsZ], rZ0, rZ1, incr_Z); + + /*--------------------------------------------------------*\ + ! Apply the boundary extension on the working buffer ap- ! + ! propriate to the specified wavelet kernel. ! + \*--------------------------------------------------------*/ + boundary_extension[control->KernelZ](&memory[id][filter_tapsZ], rZ0, rZ1, filter_tapsZ); + + /*--------------------------------------------------------*\ + ! Perform the inverse wavelet transform on the current ! + ! spatial slice. ! + \*--------------------------------------------------------*/ + inverse_wavelet_transform[control->KernelZ](working_buffer, rZ0, rZ1); + + /*--------------------------------------------------------*\ + ! Copy the decompressed flow field samples from the work- ! + ! ing buffer to the tile parameter memory. ! + \*--------------------------------------------------------*/ + buffer_flush_inverse(data, working_buffer, rZ0, rZ1, incr_Z); + } + } + } + } + + if(level < control->decompY && (rY1 - rY0) > 1) + { + /*--------------------------------------------------------*\ + ! Associate the working buffer pointer to the allocated ! + ! memory block. The working buffer points to the appropri- ! + ! ate starting point in the memory block, accounting for ! + ! for the taps of the wavelet kernel selected for the ! + ! second spatial dimension. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsY]; + + /*--------------------------------------------------------*\ + ! Adjust the working buffer pointer in case of an odd ! + ! length row starting point. ! + \*--------------------------------------------------------*/ + if(rY0 % 2) + { + working_buffer++; + } + + /*--------------------------------------------------------*\ + ! Walk trough all the temporal and spatial slices as well ! + ! as columns. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp for collapse(3) + #endif + for(t = 0; t < (rTS1 - rTS0); ++t) + { + for(z = 0; z < (rZ1 - rZ0); ++z) + { + for(x = 0; x < (rX1 - rX0); ++x) + { + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next row. ! + \*--------------------------------------------------------*/ + data = parameter->data + x * incr_X + z * incr_Z + t * incr_TS; + + /*--------------------------------------------------------*\ + ! In the event that the current row and resolution only ! + ! encompasses 1 value, the sample will remain unaltered. ! + ! In case of an odd starting point the sample will be ! + ! doubled. ! + \*--------------------------------------------------------*/ + if((rY1 - rY0) == 1) + { + if(rY0 & 2) + { + data[0].f /= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the x-th tile parameter ! + ! row. ! + \*--------------------------------------------------------*/ + fill_inverse_buffer(data, &memory[id][filter_tapsY], rY0, rY1, incr_Y); + + /*--------------------------------------------------------*\ + ! Apply the boundary extension on the working buffer ap- ! + ! propriate to the specified wavelet kernel. ! + \*--------------------------------------------------------*/ + boundary_extension[control->KernelY](&memory[id][filter_tapsY], rY0, rY1, filter_tapsY); + + /*--------------------------------------------------------*\ + ! Perform the inverse wavelet transform on the current ! + ! column. ! + \*--------------------------------------------------------*/ + inverse_wavelet_transform[control->KernelY](working_buffer, rY0, rY1); + + /*--------------------------------------------------------*\ + ! Copy the decompressed flow field samples from the work- ! + ! ing buffer to the tile parameter memory. ! + \*--------------------------------------------------------*/ + buffer_flush_inverse(data, working_buffer, rY0, rY1, incr_Y); + } + } + } + } + + if(level < control->decompX && (rX1 - rX0) > 1) + { + /*--------------------------------------------------------*\ + ! Associate the working buffer pointer to the allocated ! + ! memory block. The working buffer points to the appropri- ! + ! ate starting point in the memory block, accounting for ! + ! for the taps of the wavelet kernel selected for the ! + ! first spatial dimension. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsX]; + + /*--------------------------------------------------------*\ + ! Adjust the working buffer pointer in case of an odd ! + ! length column starting point. ! + \*--------------------------------------------------------*/ + if(rX0 % 2) + { + working_buffer++; + } + + /*--------------------------------------------------------*\ + ! Walk trough all the temporal and spatial slices as well ! + ! as rows. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp for collapse(3) + #endif + for(t = 0; t < (rTS1 - rTS0); ++t) + { + for(z = 0; z < (rZ1 - rZ0); ++z) + { + for(y = 0; y < (rY1 - rY0); ++y) + { + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next column. ! + \*--------------------------------------------------------*/ + data = parameter->data + y * incr_Y + z * incr_Z + t * incr_TS; + + /*--------------------------------------------------------*\ + ! In the event that the current column and resolution only ! + ! encompasses 1 value, the sample will remain unaltered. ! + ! In case of an odd starting point the sample will be ! + ! doubled. ! + \*--------------------------------------------------------*/ + if((rX1 - rX0) == 1) + { + if(rX0 & 2) + { + data[0].f /= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the y-th tile parameter ! + ! column. ! + \*--------------------------------------------------------*/ + fill_inverse_buffer(data, &memory[id][filter_tapsX], rX0, rX1, incr_X); + + /*--------------------------------------------------------*\ + ! Apply the boundary extension on the working buffer ap- ! + ! propriate to the specified wavelet kernel. ! + \*--------------------------------------------------------*/ + boundary_extension[control->KernelX](&memory[id][filter_tapsX], rX0, rX1, filter_tapsX); + + /*--------------------------------------------------------*\ + ! Perform the inverse wavelet transform on the current ! + ! column. ! + \*--------------------------------------------------------*/ + inverse_wavelet_transform[control->KernelX](working_buffer, rX0, rX1); + + /*--------------------------------------------------------*\ + ! Copy the decompressed flow field samples from the work- ! + ! ing buffer to the tile parameter memory. ! + \*--------------------------------------------------------*/ + buffer_flush_inverse(data, working_buffer, rX0, rX1, incr_X); + } + } + } + } + } + } + + /*--------------------------------------------------------*\ + ! Deallocate the memory array and memory blocks. ! + \*--------------------------------------------------------*/ + for(i = 0; i < nThreads; ++i) + { + free(memory[i]); + } + free(memory); + + return 0; +} \ No newline at end of file diff --git a/src/library/libbwc.c b/src/library/libbwc.c new file mode 100755 index 0000000..0f321af --- /dev/null +++ b/src/library/libbwc.c @@ -0,0 +1,4600 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| || +|| Version 0.1.1 || +|| || +|| DESCRIPTION: || +|| ------------ || +|| Big Whoop is a compression codec for the lossy compression of IEEE 754 floating point arrays defined on curvelinear || +|| compute grids. || +|| || +|| FILE REFERENCES: || +|| ---------------- || +|| || +|| Name I/O Description || +|| ---- --- ----------- || +|| none - - || +|| || +|| || +|| PRIVATE FUNCTIONS: || +|| ------------------ || +|| - initialize_precinct || +|| - subband_gain || +|| - initialize_subband || +|| - create_field || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| - bwc_initialize_field || +|| - bwc_add_param || +|| - bwc_set_error_resilience || +|| - bwc_set_quantization_style || +|| - bwc_set_progression || +|| - bwc_set_kernels || +|| - bwc_set_decomp || +|| - bwc_set_precincts || +|| - bwc_set_codeblocks || +|| - bwc_set_qm || +|| - bwc_set_tiles || +|| - bwc_create_compression || +|| - bwc_kill_compression || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 10.10.2017 Patrick Vogler B87D120 V 0.1.0 source file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ + +/************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\************************************************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bitstream.h" +#include "constants.h" +#include "macros.h" +#include "types.h" +#include "codestream.h" +#include "dwt.h" +#include "tier1.h" +#include "tier2.h" +#include "tagtree.h" + +/************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uint8 initialize_precinct(bwc_field *const field, bwc_precinct *precinct, ! +! -------------- const uint32 dX, const uint32 dY, ! +! const uint32 dZ, const uint32 dTS) ! +! ! +! ! +! DESCRIPTION: ! +! ------------ ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! precinct bwc_precinct* - Structure defining a bwc precinct. ! +! ! +! dX, dY, dZ, dTS unsigned int(32 bit) - Defines the offset of the codeblock ! +! with regards to the current subband. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned int (8 bit) - Subband gain factor in log2 factor. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 24.05.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uint8 +initialize_precinct(bwc_field *const field, bwc_precinct *precinct, const uint32 dX, const uint32 dY, + const uint32 dZ, const uint32 dTS) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 cb, cbSizeX, cbSizeY, cbSizeZ, cbSizeTS; + uint16 cb_X, cb_Y, cb_Z, cb_TS; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_prec_ctrl *prec_control; + bwc_prec_inf *prec_info; + bwc_codeblock *codeblock; + bwc_cblk_ctrl *cblk_control; + bwc_cblk_inf *cblk_info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(precinct); + + /*--------------------------------------------------------*\ + ! Save the global control as well as the precinct control ! + ! and info structure to temporary variables to make the ! + ! code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + prec_control = &precinct->control; + prec_info = &precinct->info; + + /*--------------------------------------------------------*\ + ! Evaluate the global codeblock size for easy access. ! + \*--------------------------------------------------------*/ + cbSizeX = 1 << control->cbX ; + cbSizeY = 1 << control->cbY ; + cbSizeZ = 1 << control->cbZ ; + cbSizeTS = 1 << control->cbTS; + + /*--------------------------------------------------------*\ + ! Calculate the number of codeblock to cover precinct p in ! + ! subband s according to the corresponding equation from ! + ! JPEG2000 by D. S. Taubman and M. W. Marcellin (p.462). ! + \*--------------------------------------------------------*/ + prec_control->numCbX = (uint16)((prec_info->X0 == prec_info->X1) ? 0 : (ceil((float)prec_info->X1 /cbSizeX) - + floor((float)prec_info->X0 / cbSizeX))); + prec_control->numCbY = (uint16)((prec_info->Y0 == prec_info->Y1) ? 0 : (ceil((float)prec_info->Y1 /cbSizeY) - + floor((float)prec_info->Y0 / cbSizeY))); + prec_control->numCbZ = (uint16)((prec_info->Z0 == prec_info->Z1) ? 0 : (ceil((float)prec_info->Z1 /cbSizeZ) - + floor((float)prec_info->Z0 / cbSizeZ))); + prec_control->numCbTS = (uint16)((prec_info->TS0 == prec_info->TS1) ? 0 : (ceil((float)prec_info->TS1/cbSizeTS)- + floor((float)prec_info->TS0/ cbSizeTS))); + + prec_control->number_of_codeblocks = (uint64)prec_control->numCbX * prec_control->numCbY * prec_control->numCbZ * prec_control->numCbTS; + + /*--------------------------------------------------------*\ + ! Evaluate if the current precinct features any codeblocks.! + \*--------------------------------------------------------*/ + if(prec_control->number_of_codeblocks) + { + /*--------------------------------------------------------*\ + ! Initialize the msbs and inclusion tagtree for the cur- ! + ! rent precinct. ! + \*--------------------------------------------------------*/ + prec_control->tag_msbs = initialize_tagtree(prec_control->numCbX, prec_control->numCbY, + prec_control->numCbZ, prec_control->numCbTS); + prec_control->tag_inclusion = initialize_tagtree(prec_control->numCbX, prec_control->numCbY, + prec_control->numCbZ, prec_control->numCbTS); + + /*--------------------------------------------------------*\ + ! Allocate, walk through and setup the codeblock structure ! + ! according to the specified compression parameters. ! + \*--------------------------------------------------------*/ + precinct->codeblock = calloc(prec_control->number_of_codeblocks, sizeof(bwc_codeblock)); + if(!precinct->codeblock) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + for(cb_TS = 0, cb = 0; cb_TS < prec_control->numCbTS; ++cb_TS) + { + for(cb_Z = 0; cb_Z < prec_control->numCbZ; ++cb_Z) + { + for(cb_Y = 0; cb_Y < prec_control->numCbY; ++cb_Y) + { + for(cb_X = 0; cb_X < prec_control->numCbX; ++cb_X, ++cb) + { + /*--------------------------------------------------------*\ + ! Allocate the info and control structure for the current ! + ! codeblock. ! + \*--------------------------------------------------------*/ + codeblock = &precinct->codeblock[cb]; + codeblock->encoded_block = calloc(1, sizeof(bwc_encoded_cblk)); + if(!codeblock->encoded_block) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + cblk_info = &codeblock->info; + cblk_control = &codeblock->control; + + /*--------------------------------------------------------*\ + ! Allocate the memory block used to store the coding pass ! + ! contributions for the specified quality layers and setup ! + ! the pointer used to access the integer array. ! + \*--------------------------------------------------------*/ + cblk_control->memory = calloc(control->nLayers + 1, sizeof(int16)); + if(!cblk_control->memory) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + cblk_control->cp_contr = &cblk_control->memory[1]; + + cblk_control->beta = 3; + cblk_control->beta_est = 3; + + /*--------------------------------------------------------*\ + ! Calculate the boundaries for the current codeblock ac- ! + ! cording to the corresponding equation from JPEG2000 by ! + ! David S. Taubman and Michael W. Marcellin (p.460). ! + \*--------------------------------------------------------*/ + cblk_info->X0 = dX + (uint32)MAX(prec_info->X0 , cbSizeX * (cb_X + (uint32)floor((float)prec_info->X0 / cbSizeX ))); + cblk_info->Y0 = dY + (uint32)MAX(prec_info->Y0 , cbSizeY * (cb_Y + (uint32)floor((float)prec_info->Y0 / cbSizeY ))); + cblk_info->Z0 = dZ + (uint32)MAX(prec_info->Z0 , cbSizeZ * (cb_Z + (uint32)floor((float)prec_info->Z0 / cbSizeZ ))); + cblk_info->TS0 = dTS + (uint16)MAX(prec_info->TS0, cbSizeTS * (cb_TS + (uint32)floor((float)prec_info->TS0/ cbSizeTS))); + cblk_info->X1 = dX + (uint32)MIN(prec_info->X1 , cbSizeX * (cb_X + (uint32)floor((float)prec_info->X0 / cbSizeX ) + 1)); + cblk_info->Y1 = dY + (uint32)MIN(prec_info->Y1 , cbSizeY * (cb_Y + (uint32)floor((float)prec_info->Y0 / cbSizeY ) + 1)); + cblk_info->Z1 = dZ + (uint32)MIN(prec_info->Z1 , cbSizeZ * (cb_Z + (uint32)floor((float)prec_info->Z0 / cbSizeZ ) + 1)); + cblk_info->TS1 = dTS + (uint16)MIN(prec_info->TS1, cbSizeTS * (cb_TS + (uint32)floor((float)prec_info->TS0/ cbSizeTS) + 1)); + } + } + } + } + } + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uint8 subband_gain(const uint8 highband_flag) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function calculates the gain for a specific subband in log2 format according to the ! +! number of applied 1-D wavelet transforms. The subband gain is calculated by evaluating the ! +! hamming weight of the highband flag. (see https://en.wikipedia.org/wiki/Hamming_weight) ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! highband_flag unsigned in (8 bit) - Flag defining the number and types of ! +! 1-D wavelet of transforms applied to ! +! the subband. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned int (8 bit) - Subband gain factor in log2 factor. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 15.05.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uint8 subband_gain(const uint8 highband_flag) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint8 temp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(highband_flag <= DIM_ALL); + + /*--------------------------------------------------------*\ + ! Save the highband flag in a temporary variable. ! + \*--------------------------------------------------------*/ + temp = highband_flag; + + /*--------------------------------------------------------*\ + ! Calculate the subband gain according to the number of ! + ! applied 1-D wavelet transforms. ! + \*--------------------------------------------------------*/ + temp -= (temp >> 1) & 0x55; + temp = (temp & 0x33) + ((temp >> 2) & 0x33); + return (temp + (temp >> 4)) & 0x0F; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar initialize_subband(bwc_field *const field, bwc_parameter *const parameter, ! +! -------------- bwc_resolution *const resolution, ! +! bwc_subband *const subband, ! +! int32 resolution_level, ! +! int16 highband_flag) ! +! ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function initializes the bwc_subband structure with all necessary standard parameters ! +! to (de)compress a floating point array with nX * nY * nZ grid points, nTS timesteps and ! +! nPar parameters. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! parameter bwc_parameter* - Structure defining a bwc tile parameter.! +! ! +! resolution bwc_resolution* - Structure defining a bwc resolution ! +! level. ! +! ! +! subband bwc_subband* - Structure defining a bwc subband. ! +! ! +! resolution_level signed int(32 bit) - Defines the current resolution level. ! +! ! +! highband_flag signed int(16 bit) - Defines the type of highband the cur- ! +! rent subband represents. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 12.12.2017 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uchar +initialize_subband(bwc_field *const field, bwc_parameter *const parameter, bwc_resolution *const resolution, + bwc_subband *const subband, + int32 resolution_level, + int16 highband_flag) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 p, pSizeX, pSizeY, pSizeZ, pSizeTS; + uint64 sb_sX, sb_sY, sb_sZ, sb_sTS; + uint32 Rb; + uint16 p_X, p_Y, p_Z, p_TS; + int8 decomp_level; + int8 level_X, level_Y, level_Z, level_TS; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_param_ctrl *param_control; + bwc_param_inf *param_info; + bwc_res_ctrl *res_control; + bwc_res_inf *res_info; + bwc_subb_ctrl *subb_control; + bwc_subb_inf *subb_info; + bwc_prec_ctrl *prec_control; + bwc_prec_inf *prec_info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(resolution); + assert(subband); + assert(resolution_level <= field->control.nDecomp + 1); + assert(highband_flag <= DIM_ALL); + + /*--------------------------------------------------------*\ + ! Save the global, parameter, resolution and subband con- ! + ! trol and info structures to temporary variables to make ! + ! the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + param_control = ¶meter->control; + param_info = ¶meter->info; + + res_control = &resolution->control; + res_info = &resolution->info; + + subb_control = &subband->control; + subb_info = &subband->info; + + /*--------------------------------------------------------*\ + ! Evaluate the number of decompositions in each temporal & ! + ! spatial directions according to the the global decompo - ! + ! sition level for which the subband is initialized. ! + \*--------------------------------------------------------*/ + decomp_level = control->nDecomp - resolution_level + 1; + + level_X = (decomp_level > control->decompX ) ? control->decompX : decomp_level; + level_Y = (decomp_level > control->decompY ) ? control->decompY : decomp_level; + level_Z = (decomp_level > control->decompZ ) ? control->decompZ : decomp_level; + level_TS = (decomp_level > control->decompTS) ? control->decompTS : decomp_level; + + /*--------------------------------------------------------*\ + ! Calculate the boundaries for the current subband accord- ! + ! ing to the corresponding equation from JPEG2000 by David ! + ! S. Taubman and Michael W. Marcellin (p.460). ! + \*--------------------------------------------------------*/ + subb_info->X0 = (uint64)ceil( ((float)param_info->X0 / (1 << level_X)) - 0.5 * ((highband_flag & DIM_X) >> 0)); + subb_info->Y0 = (uint64)ceil( ((float)param_info->Y0 / (1 << level_Y)) - 0.5 * ((highband_flag & DIM_Y) >> 1)); + subb_info->Z0 = (uint64)ceil( ((float)param_info->Z0 / (1 << level_Z)) - 0.5 * ((highband_flag & DIM_Z) >> 2)); + subb_info->TS0 = (uint16)ceil( ((float)param_info->TS0 / (1 << level_TS)) - 0.5 * ((highband_flag & DIM_TS) >> 3)); + subb_info->X1 = (uint64)ceil( ((float)param_info->X1 / (1 << level_X)) - 0.5 * ((highband_flag & DIM_X) >> 0)); + subb_info->Y1 = (uint64)ceil( ((float)param_info->Y1 / (1 << level_Y)) - 0.5 * ((highband_flag & DIM_Y) >> 1)); + subb_info->Z1 = (uint64)ceil( ((float)param_info->Z1 / (1 << level_Z)) - 0.5 * ((highband_flag & DIM_Z) >> 2)); + subb_info->TS1 = (uint16)ceil( ((float)param_info->TS1 / (1 << level_TS)) - 0.5 * ((highband_flag & DIM_TS) >> 3)); + + /*--------------------------------------------------------*\ + ! Evaluate the dynamic range (Rb) of the current subband. ! + \*--------------------------------------------------------*/ + Rb = PREC_BIT + subband_gain(highband_flag); + + /*--------------------------------------------------------*\ + ! Save the highband flag in the subband control structure ! + ! and evaluate the energy gain factor for the current sub- ! + ! band. ! + \*--------------------------------------------------------*/ + subb_control->highband_flag = highband_flag; + subb_info->dwt_gain = get_dwt_energy_gain(field, highband_flag, decomp_level); + + /*--------------------------------------------------------*\ + ! Evaluate the quantization exponent, mantissa, step size ! + ! and effective step size according to the specified quan- ! + ! tization style. ! + \*--------------------------------------------------------*/ + if(control->quantization_style == bwc_qt_none) + { + /*--------------------------------------------------------*\ + ! If no quantization is wanted the mantissa is set to 0 ! + ! while the exponent is set to the dynamic range of the ! + ! subband in order to obtain a step size of 1. ! + \*--------------------------------------------------------*/ + subb_control->qt_exponent = (uint8) Rb; + subb_control->qt_mantissa = (uint16) 0; + subb_control->qt_step_size = 1; + subb_control->qt_effective_step_size = 1; + } + else + { + /*--------------------------------------------------------*\ + ! For a derrived quantization style the exponent is a- ! + ! dapted to the current resolution level and the (effec- ! + ! tive) step size is evaluated according to equation ! + ! (10.26) from JPEG2000 by David S. Taubman and Michael ! + ! W. Marcellin (p.439). ! + \*--------------------------------------------------------*/ + subb_control->qt_exponent = (uint8) control->qt_exponent + ((resolution_level == 0) ? 0 : 1 - resolution_level); + subb_control->qt_mantissa = (uint16) control->qt_mantissa; + subb_control->qt_step_size = (1.0f + ((double)subb_control->qt_mantissa / (1 << 11))) / pow(2,subb_control->qt_exponent); + subb_control->qt_effective_step_size = (1.0f + ((double)subb_control->qt_mantissa / (1 << 11))); + if(subb_control->qt_exponent > Rb) + { + subb_control->qt_effective_step_size /= pow(2,subb_control->qt_exponent - Rb); + } + else + { + subb_control->qt_effective_step_size *= pow(2,Rb - subb_control->qt_exponent); + } + } + + /*--------------------------------------------------------*\ + ! Evaluate the dynamic range of the subband after the ! + ! transformation stage. ! + \*--------------------------------------------------------*/ + subb_control->Kmax = MAX(0, control->guard_bits + subb_control->qt_exponent - 1); + + /*--------------------------------------------------------*\ + ! Evaluate the global precinct size for easy access. ! + \*--------------------------------------------------------*/ + pSizeX = 1 << control->precSizeX; + pSizeY = 1 << control->precSizeY; + pSizeZ = 1 << control->precSizeZ; + pSizeTS = 1 << control->precSizeTS; + + /*--------------------------------------------------------*\ + ! Evaluate the start coordinates for the current subband. ! + \*--------------------------------------------------------*/ + sb_sX = (highband_flag & DIM_X) ? (parameter->resolution[resolution_level - 1].info.X1 - + parameter->resolution[resolution_level - 1].info.X0 ) : 0; + sb_sY = (highband_flag & DIM_Y) ? (parameter->resolution[resolution_level - 1].info.Y1 - + parameter->resolution[resolution_level - 1].info.Y0 ) : 0; + sb_sZ = (highband_flag & DIM_Z) ? (parameter->resolution[resolution_level - 1].info.Z1 - + parameter->resolution[resolution_level - 1].info.Z0 ) : 0; + sb_sTS = (highband_flag & DIM_TS) ? (parameter->resolution[resolution_level - 1].info.TS1 - + parameter->resolution[resolution_level - 1].info.TS0) : 0; + + /*--------------------------------------------------------*\ + ! Evaluate if the current resolution level features any ! + ! precincts. ! + \*--------------------------------------------------------*/ + if(res_control->number_of_precincts) + { + /*--------------------------------------------------------*\ + ! Allocate, walk through and setup the precinct structure ! + ! according to the specified compression parameters. ! + \*--------------------------------------------------------*/ + subband->precinct = calloc(res_control->number_of_precincts, sizeof(bwc_precinct)); + if(!subband->precinct) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + for(p_TS = 0, p = 0; p_TS < res_control->numPTS; ++p_TS) + { + for(p_Z = 0; p_Z < res_control->numPZ; ++p_Z) + { + for(p_Y = 0; p_Y < res_control->numPY; ++p_Y) + { + for(p_X = 0; p_X < res_control->numPX; ++p_X, ++p) + { + /*--------------------------------------------------------*\ + ! Save the precinct info and control structure to tempo- ! + ! rary variables to make the code more readable. ! + \*--------------------------------------------------------*/ + prec_control = &subband->precinct[p].control; + prec_info = &subband->precinct[p].info; + + /*--------------------------------------------------------*\ + ! Calculate the boundaries for the current precinct accord-! + ! ing to the corresponding equation from JPEG2000 by David ! + ! S. Taubman and Michael W. Marcellin (p.460). ! + \*--------------------------------------------------------*/ + prec_info->X0 = (uint32)MAX(res_info->X0 , pSizeX * (p_X + (uint32)floor(res_info->X0 / pSizeX))); + prec_info->Y0 = (uint32)MAX(res_info->Y0 , pSizeY * (p_Y + (uint32)floor(res_info->Y0 / pSizeY))); + prec_info->Z0 = (uint32)MAX(res_info->Z0 , pSizeZ * (p_Z + (uint32)floor(res_info->Z0 / pSizeZ))); + prec_info->TS0 = (uint16)MAX(res_info->TS0, pSizeTS * (p_TS + (uint32)floor(res_info->TS0/ pSizeTS))); + prec_info->X1 = (uint32)MIN(res_info->X1 , pSizeX * (p_X + (uint32)floor(res_info->X0 / pSizeX) + 1)); + prec_info->Y1 = (uint32)MIN(res_info->Y1 , pSizeY * (p_Y + (uint32)floor(res_info->Y0 / pSizeY) + 1)); + prec_info->Z1 = (uint32)MIN(res_info->Z1 , pSizeZ * (p_Z + (uint32)floor(res_info->Z0 / pSizeZ) + 1)); + prec_info->TS1 = (uint16)MIN(res_info->TS1, pSizeTS * (p_TS + (uint32)floor(res_info->TS0/ pSizeTS)+ 1)); + + if((control->nDecomp - control->decompX) < resolution_level) + { + prec_info->X0 = (uint32) ceil(((float)prec_info->X0 / 2) - 0.5 * ((highband_flag & DIM_X) >> 0)); + prec_info->X1 = (uint32) ceil(((float)prec_info->X1 / 2) - 0.5 * ((highband_flag & DIM_X) >> 0)); + } + + if((control->nDecomp - control->decompY) < resolution_level) + { + prec_info->Y0 = (uint32) ceil(((float)prec_info->Y0 / 2) - 0.5 * ((highband_flag & DIM_Y) >> 1)); + prec_info->Y1 = (uint32) ceil(((float)prec_info->Y1 / 2) - 0.5 * ((highband_flag & DIM_Y) >> 1)); + } + + if((control->nDecomp - control->decompZ) < resolution_level) + { + prec_info->Z0 = (uint32) ceil(((float)prec_info->Z0 / 2) - 0.5 * ((highband_flag & DIM_Z) >> 2)); + prec_info->Z1 = (uint32) ceil(((float)prec_info->Z1 / 2) - 0.5 * ((highband_flag & DIM_Z) >> 2)); + } + + if((control->nDecomp - control->decompTS) < resolution_level) + { + prec_info->TS0 = (uint16) ceil(((float)prec_info->TS0 / 2) - 0.5 * ((highband_flag & DIM_TS) >> 3)); + prec_info->TS1 = (uint16) ceil(((float)prec_info->TS1 / 2) - 0.5 * ((highband_flag & DIM_TS) >> 3)); + } + + /*--------------------------------------------------------*\ + ! Initialize the precinct structure according to the speci-! + ! fied compression parameters. ! + \*--------------------------------------------------------*/ + initialize_precinct(field, &subband->precinct[p], (uint32)sb_sX - subb_info->X0, (uint32)sb_sY - subb_info->Y0, + (uint32)sb_sZ - subb_info->Z0, (uint32)sb_sTS - subb_info->TS0); + + /*--------------------------------------------------------*\ + ! Update the number of codeblocks for the current parame- ! + ! ter. ! + \*--------------------------------------------------------*/ + param_control->number_of_codeblocks += prec_control->number_of_codeblocks; + } + } + } + } + } + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_header_append_aux(bwc_field *const field, bwc_packed_stream *const aux) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the main header for the compressed codestream with an auxiliary ! +! information block. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! aux unsigned char* - Memory handle for the auxiliary infor- ! +! mation block. ! +! ! +! size unsigned int(32 bit) - Size of the auxiliary information block.! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 12.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uchar +header_append_aux(bwc_field *const field, bwc_packed_stream *const aux) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(aux); + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Check if the main header is already defined in the field ! + ! structure. ! + \*--------------------------------------------------------*/ + if(!control->header.memory) + { + fprintf(stderr,"o==========================================================o\n"\ + "| ERROR: Main header not defined |\n"\ + "| |\n"\ + "| Unable to append auxiliary information since the |\n"\ + "| main header has not yet been created. Appending |\n"\ + "| information to the end of the main header can |\n"\ + "| only be done after the bwc_create_compression |\n"\ + "| function has been called. |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + return 1; + } + + /*--------------------------------------------------------*\ + ! Check if the main header would exceed the maximum number ! + ! of allowable bits after appending the auxiliary ! + ! information. ! + \*--------------------------------------------------------*/ + if(((uint64)control->header.size + aux->size) >= 0xFFFFFFFF) + { + fprintf(stderr,"o==========================================================o\n"\ + "| ERROR: Main header exceeds maximum size limit |\n"\ + "| |\n"\ + "| Appending the auxiliary information to the main |\n"\ + "| header would exceed its maximum size limit of |\n"\ + "| 4294967295 bytes. |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + return 1; + } + + if(codestream_write_aux(&control->header, aux)) + { + return 1; + } + + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_header_append_com(bwc_field *const field, bwc_packed_stream *const com) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the main header for the compressed codestream with a comment ! +! block. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! com unsigned char* - Memory handle for the auxiliary infor- ! +! mation block. ! +! ! +! size unsigned int(32 bit) - Size of the auxiliary information block.! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 12.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uchar +header_append_com(bwc_field *const field, bwc_packed_stream *const com) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Check if the main header is already defined in the field ! + ! structure. ! + \*--------------------------------------------------------*/ + if(!control->header.memory) + { + fprintf(stderr,"o==========================================================o\n"\ + "| ERROR: Main header not defined |\n"\ + "| |\n"\ + "| Unable to append auxiliary information since the |\n"\ + "| main header has not yet been created. Appending |\n"\ + "| information to the end of the main header can |\n"\ + "| only be done after the bwc_create_compression |\n"\ + "| function has been called. |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + return 1; + } + + /*--------------------------------------------------------*\ + ! Check if the main header would exceed the maximum number ! + ! of allowable bits after appending the auxiliary ! + ! information. ! + \*--------------------------------------------------------*/ + if(((uint64)control->header.size + com->size) >= 0xFFFFFFFF) + { + fprintf(stderr,"o==========================================================o\n"\ + "| ERROR: Main header exceeds maximum size limit |\n"\ + "| |\n"\ + "| Appending the auxiliary information to the main |\n"\ + "| header would exceed its maximum size limit of |\n"\ + "| 4294967295 bytes. |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + return 1; + } + + if(codestream_write_com(&control->header, com)) + { + return 1; + } + + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void fill_buffer(bwc_field *const field, bwc_tile *const tile, ! +! ------------ bwc_parameter *const parameter, ! +! bwc_sample *const working_buffer, ! +! double *const data, ! +! uint64 param_size, ! +! uint16 param_id) ! +! ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to fill the working buffer with the appropriate flow field data for ! +! the specified tile parameter. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! tile bwc_tile* - Structure defining a bwc tile. ! +! ! +! parameter bwc_parameter* - Structure defining a bwc parameter. ! +! ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for a specific tile parameter. ! +! ! +! param_size uint64 - Specifies the byte size of one tile ! +! parameter. ! +! ! +! parameter uint16 - Specifies the parameter index for the ! +! current tile parameter. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 22.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +fill_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const parameter, + bwc_sample *const working_buffer, + bwc_data *const data, + uint16 param_id) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 width, height, depth, dt; + uint64 sampX, sampY, sampZ; + uint64 param_offset; + uint64 w, x, y, z; + uint16 sampTS; + uint16 t; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + bwc_float max, min; + double *src_d, *tmp_d; + float *src_f, *tmp_f; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_sample *dest; + bwc_gl_inf *info; + bwc_tile_inf *tile_info; + bwc_param_ctrl *param_control; + bwc_param_inf *param_info; + bwc_cmd_opts_ll *param; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(tile); + assert(parameter); + assert(working_buffer); + assert(data); + + /*--------------------------------------------------------*\ + ! Save the global, tile and parameter control and info ! + ! structures to temporary variables to make the code more ! + ! readable. ! + \*--------------------------------------------------------*/ + info = field->info; + + tile_info = &tile->info; + + param_control = ¶meter->control; + param_info = ¶meter->info; + + /*--------------------------------------------------------*\ + ! Calculate the offset of the current parameter in the da- ! + ! ta array. ! + \*--------------------------------------------------------*/ + param_offset = 0; + param = data->info.parameter->root; + + while(param != NULL && param->id < param_id) + { + if(param->precision == param_info->precision) + { + param_offset += param->size; + } + param = param -> next; + } + + /*--------------------------------------------------------*\ + ! Associate the working buffer with the data pointer in ! + ! the bwc_parameter structure. ! + \*--------------------------------------------------------*/ + parameter->data = working_buffer; + + /*--------------------------------------------------------*\ + ! Initialize the maximum and minimum parameter value. ! + \*--------------------------------------------------------*/ + max = param_info->parameter_max; + min = param_info->parameter_min; + + /*--------------------------------------------------------*\ + ! Calculate the width, height, depth and dt of the current ! + ! tile parameter. ! + \*--------------------------------------------------------*/ + width = param_info->X1 - param_info->X0; + height = param_info->Y1 - param_info->Y0; + depth = param_info->Z1 - param_info->Z0; + dt = param_info->TS1 - param_info->TS0; + + sampX = 1 << param_control->sampX; + sampY = 1 << param_control->sampY; + sampZ = 1 << param_control->sampZ; + sampTS = 1 << param_control->sampTS; + + /*--------------------------------------------------------*\ + ! Check if the parameter is single or double precision and ! + ! handle the field accordingly. ! + \*--------------------------------------------------------*/ + if(param_info->precision == 8) + { + /*--------------------------------------------------------*\ + ! Safe the field pointer to a temporary variable to make ! + ! the code more readable. ! + \*--------------------------------------------------------*/ + tmp_d = data->field.d; + + /*--------------------------------------------------------*\ + ! Walk through the tile parameter working buffer. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp parallel for collapse(3) private(dest, src_d, w, x) reduction(max:max) reduction(min:min) + #endif + for(t = 0; t < dt; ++t) + { + for(z = 0; z < depth; ++z) + { + for(y = 0; y < height; ++y) + { + /*--------------------------------------------------------*\ + ! Advance the temporary data and buffer pointers to their ! + ! appropriate positions in the working buffer and data ! + ! arrays. ! + \*--------------------------------------------------------*/ + src_d = &tmp_d[param_offset + tile_info->X0 + info->nX * + (tile_info->Y0 + y * sampY + info->nY * + (tile_info->Z0 + z * sampZ + info->nZ * + t * sampTS))]; + + dest = &working_buffer[(uint64) width * (y + height * (z + depth * t))]; + + for(w = 0, x = 0; w < width; ++w, x += sampX) + { + /*--------------------------------------------------------*\ + ! Copy the data sample to the working buffer. ! + \*--------------------------------------------------------*/ + dest[w].f = (bwc_float)src_d[x]; + + /*--------------------------------------------------------*\ + ! Update the maximum and minimum parameter value. ! + \*--------------------------------------------------------*/ + max = MAX(max, dest[w].f); + min = MIN(min, dest[w].f); + } + } + } + } + } + else + { + /*--------------------------------------------------------*\ + ! Safe the field pointer to a temporary variable to make ! + ! the code more readable. ! + \*--------------------------------------------------------*/ + tmp_f = data->field.f; + + /*--------------------------------------------------------*\ + ! Walk through the tile parameter working buffer. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp parallel for collapse(3) private(dest, src_f, w, x) reduction(max:max) reduction(min:min) + #endif + for(t = 0; t < dt; ++t) + { + for(z = 0; z < depth; ++z) + { + for(y = 0; y < height; ++y) + { + /*--------------------------------------------------------*\ + ! Advance the temporary data and buffer pointers to their ! + ! appropriate positions in the working buffer and data ! + ! arrays. ! + \*--------------------------------------------------------*/ + src_f = &tmp_f[param_offset + tile_info->X0 + info->nX * + (tile_info->Y0 + y * sampY + info->nY * + (tile_info->Z0 + z * sampZ + info->nZ * + t * sampTS))]; + + dest = &working_buffer[(uint64) width * (y + height * (z + depth * t))]; + + for(w = 0, x = 0; w < width; ++w, x += sampX) + { + /*--------------------------------------------------------*\ + ! Copy the data sample to the working buffer. ! + \*--------------------------------------------------------*/ + dest[w].f = (bwc_float)src_f[x]; + + /*--------------------------------------------------------*\ + ! Update the maximum and minimum parameter value. ! + \*--------------------------------------------------------*/ + max = MAX(max, dest[w].f); + min = MIN(min, dest[w].f); + } + } + } + } + } + + /*--------------------------------------------------------*\ + ! Update the maximum and minimum parameter value in the ! + ! parameter structure. ! + \*--------------------------------------------------------*/ + param_info->parameter_max = max; + param_info->parameter_min = min; + + /*--------------------------------------------------------*\ + ! Calculate the constants used to normalize the tile pa- ! + ! rameter to the range of [-1,1). ! + \*--------------------------------------------------------*/ + param_control->alpha = (param_info->parameter_max + param_info->parameter_min)/2.0f; + param_control->beta = 2.0f/(param_info->parameter_max - param_info->parameter_min); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void fill_buffer(bwc_field *const field, bwc_tile *const tile, ! +! ------------ bwc_parameter *const parameter, ! +! bwc_sample *const working_buffer, ! +! double *const data, ! +! uint64 param_size, ! +! uint16 param_id) ! +! ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to flush the working buffer to the flow field data memory block. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! tile bwc_tile* - Structure defining a bwc tile. ! +! ! +! parameter bwc_parameter* - Structure defining a bwc parameter. ! +! ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for a specific tile parameter. ! +! ! +! param_size uint64 - Specifies the byte size of one tile ! +! parameter. ! +! ! +! parameter uint16 - Specifies the parameter index for the ! +! current tile parameter. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 22.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +flush_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const parameter, + bwc_sample *const working_buffer, + bwc_data *const data, + uint16 param_id) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 width, height, depth, dt; + uint64 nX, nY, nZ; + uint64 param_offset; + uint64 x, y, z; + uint16 t; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + double *dst_d, *tmp_d; + float *dst_f, *tmp_f; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_sample *src; + bwc_gl_inf *info; + bwc_param_ctrl *param_control; + bwc_param_inf *param_info; + bwc_cmd_opts_ll *param; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(tile); + assert(parameter); + assert(working_buffer); + assert(data); + + /*--------------------------------------------------------*\ + ! Save the global, tile and parameter control and info ! + ! structures to temporary variables to make the code more ! + ! readable. ! + \*--------------------------------------------------------*/ + info = field->info; + + param_control = ¶meter->control; + param_info = ¶meter->info; + + /*--------------------------------------------------------*\ + ! Calculate the offset of the current parameter in the da- ! + ! ta array. ! + \*--------------------------------------------------------*/ + param_offset = 0; + param = data->info.parameter->root; + + while(param != NULL && param->id < param_id) + { + if(param->precision == param_info->precision) + { + param_offset += param->size; + } + param = param -> next; + } + + /*--------------------------------------------------------*\ + ! Calculate the number of data points in all spatial dimen-! + ! sions after subsampling. ! + \*--------------------------------------------------------*/ + nX = info->nX >> param_control->sampX ; + nY = info->nY >> param_control->sampY ; + nZ = info->nZ >> param_control->sampZ ; + + /*--------------------------------------------------------*\ + ! Calculate the width, height, depth and dt of the current ! + ! tile parameter. ! + \*--------------------------------------------------------*/ + width = param_info->X1 - param_info->X0; + height = param_info->Y1 - param_info->Y0; + depth = param_info->Z1 - param_info->Z0; + dt = param_info->TS1 - param_info->TS0; + + /*--------------------------------------------------------*\ + ! Check if the parameter is single or double precision and ! + ! handle the field accordingly. ! + \*--------------------------------------------------------*/ + if(param_info->precision == 8) + { + /*--------------------------------------------------------*\ + ! Safe the field pointer to a temporary variable to make ! + ! the code more readable. ! + \*--------------------------------------------------------*/ + tmp_d = data->field.d; + + /*--------------------------------------------------------*\ + ! Walk through the tile parameter working buffer. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp parallel for collapse(3) private(dst_d, src, x) + #endif + for(t = 0; t < dt; ++t) + { + for(z = 0; z < depth; ++z) + { + for(y = 0; y < height; ++y) + { + /*--------------------------------------------------------*\ + ! Advance the temporary data and buffer pointers to their ! + ! appropriate positions in the working buffer and data ! + ! arrays. ! + \*--------------------------------------------------------*/ + dst_d = &tmp_d[param_offset + param_info->X0 + nX * + (param_info->Y0 + y + nY * + (param_info->Z0 + z + nZ * t ))]; + + src = &working_buffer[(uint64) width * (y + height * (z + depth * t))]; + + for(x = 0; x < width; ++x) + { + /*--------------------------------------------------------*\ + ! Copy the sample to the data memory block. ! + \*--------------------------------------------------------*/ + dst_d[x] = (double)src[x].f; + } + } + } + } + } + else + { + /*--------------------------------------------------------*\ + ! Safe the field pointer to a temporary variable to make ! + ! the code more readable. ! + \*--------------------------------------------------------*/ + tmp_f = data->field.f; + + /*--------------------------------------------------------*\ + ! Walk through the tile parameter working buffer. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp parallel for collapse(3) private(dst_f, src, x) + #endif + for(t = 0; t < dt; ++t) + { + for(z = 0; z < depth; ++z) + { + for(y = 0; y < height; ++y) + { + /*--------------------------------------------------------*\ + ! Advance the temporary data and buffer pointers to their ! + ! appropriate positions in the working buffer and data ! + ! arrays. ! + \*--------------------------------------------------------*/ + dst_f = &tmp_f[param_offset + param_info->X0 + nX * + (param_info->Y0 + y + nY * + (param_info->Z0 + z + nZ * t ))]; + + src = &working_buffer[(uint64) width * (y + height * (z + depth * t))]; + + for(x = 0; x < width; ++x) + { + /*--------------------------------------------------------*\ + ! Copy the sample to the data memory block. ! + \*--------------------------------------------------------*/ + dst_f[x] = (float)src[x].f; + } + } + } + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void buff_normalize(bwc_field *const field, bwc_parameter *const parameter) ! +! ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to normalize the values v[i] of the current tile parameter to the ! +! range of [-1, 1) and scale them to a desired dynamic range: ! +! ! +! q[i] = [(v[i] - α)/β] * 2^Qm. ! +! ! +! Here, α and β define the normalization constants and Qm represents the dynamic range of ! +! the Q number format. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! parameter bwc_parameter* - Structure defining a bwc parameter. ! +! ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for a specific tile parameter. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 24.10.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +normalize_param(bwc_field *const field, bwc_parameter *const parameter) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + bwc_raw shift; + uint64 param_size; + uint64 x; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + bwc_float alpha, beta; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_param_ctrl *param_control; + bwc_param_inf *param_info; + bwc_sample *tmp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(parameter); + assert(parameter->data); + + /*--------------------------------------------------------*\ + ! Save the global control and the parameter control and ! + ! info structures to temporary variables to make the code ! + ! more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + param_control = ¶meter->control; + param_info = ¶meter->info; + + /*--------------------------------------------------------*\ + ! Save the normalization constants to temporary variables ! + ! to make the code more readable. ! + \*--------------------------------------------------------*/ + alpha = param_control->alpha; + beta = param_control->beta; + + /*--------------------------------------------------------*\ + ! Calculate the size of the current tile parameter. ! + \*--------------------------------------------------------*/ + param_size = (param_info->X1 - param_info->X0) * + (param_info->Y1 - param_info->Y0) * + (param_info->Z1 - param_info->Z0) * + (param_info->TS1 - param_info->TS0); + + /*--------------------------------------------------------*\ + ! Associate the temporary pointer with the data pointer in ! + ! the bwc_parameter structure. ! + \*--------------------------------------------------------*/ + tmp = parameter->data; + + /*--------------------------------------------------------*\ + ! Shift the Q number range to the appropriate position for ! + ! the IEEE 754 floating point number. ! + \*--------------------------------------------------------*/ + shift = (uint64)control->Qm << PREC_MANTISSA; + + /*--------------------------------------------------------*\ + ! Walk through the tile parameter working buffer. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp parallel for + #endif + for(x = 0; x < param_size; ++x) + { + /*--------------------------------------------------------*\ + ! Normalize the flow field values to the range of [-1,1). ! + \*--------------------------------------------------------*/ + tmp[x].f = (bwc_float)(tmp[x].f - alpha) * beta; + + /*--------------------------------------------------------*\ + ! Scale the flow field values to the dynamic range speci- ! + ! fied by the Qm parameter. ! + \*--------------------------------------------------------*/ + tmp[x].raw += (((tmp[x].raw & EXPONENT) == 0)&& + ((tmp[x].raw & MANTISSA) == 0)) ? 0 : shift; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void denormalize_param(bwc_field *const field, bwc_parameter *const parameter) ! +! ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to scale the decompressed values to their original dynamic range and ! +! denormalize the flow field values. ! +! ! +! q[i] = [(v[i]/2^Qm) * β] + α. ! +! ! +! Here, α and β define the normalization constants and Qm represents the dynamic range of ! +! the Q number format. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! parameter bwc_parameter* - Structure defining a bwc parameter. ! +! ! +! working_buffer bwc_sample* - Working buffer used to store flow field ! +! data for a specific tile parameter. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 24.10.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +denormalize_param(bwc_field *const field, bwc_parameter *const parameter) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + bwc_raw shift; + uint64 param_size; + uint64 x; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + bwc_float alpha, beta; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_param_inf *param_info; + bwc_sample *tmp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(parameter); + assert(parameter->data); + + /*--------------------------------------------------------*\ + ! Save the global control and the parameter info struc- ! + ! tures to temporary variables to make the code more ! + ! readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + param_info = ¶meter->info; + + /*--------------------------------------------------------*\ + ! Save the normalization constants to temporary variables ! + ! to make the code more readable. ! + \*--------------------------------------------------------*/ + alpha = (param_info->parameter_max + param_info->parameter_min)/2.0f; + beta = (param_info->parameter_max - param_info->parameter_min)/2.0f; + + /*--------------------------------------------------------*\ + ! Calculate the size of the current tile parameter. ! + \*--------------------------------------------------------*/ + param_size = (param_info->X1 - param_info->X0) * + (param_info->Y1 - param_info->Y0) * + (param_info->Z1 - param_info->Z0) * + (param_info->TS1 - param_info->TS0); + + /*--------------------------------------------------------*\ + ! Associate the temporary pointer with the data pointer in ! + ! the bwc_parameter structure. ! + \*--------------------------------------------------------*/ + tmp = parameter->data; + + /*--------------------------------------------------------*\ + ! Shift the Q number range to the appropriate position for ! + ! the IEEE 754 floating point number. ! + \*--------------------------------------------------------*/ + shift = (uint64)control->Qm << PREC_MANTISSA; + + /*--------------------------------------------------------*\ + ! Walk through the tile parameter working buffer. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp parallel for + #endif + for(x = 0; x < param_size; ++x) + { + /*--------------------------------------------------------*\ + ! Scale the flow field values to their original dynamic ! + ! range. ! + \*--------------------------------------------------------*/ + tmp[x].raw -= (((tmp[x].raw & EXPONENT) == 0)&& + ((tmp[x].raw & MANTISSA) == 0)) ? 0 : shift; + + /*--------------------------------------------------------*\ + ! Denormalize the flow field values. ! + \*--------------------------------------------------------*/ + tmp[x].f = (bwc_float)(tmp[x].f * beta) + alpha; + } +} + +/************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: bwc_field *bwc_initialize_data(...) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function initializes the bwc_data structure with all necessary parameters. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! nX ,nY, nZ unsigned int(64 bit) - Number of spatial Datapoints ! +! ! +! nTS unsigned int(16 bit) - Number of Timesteps. ! +! ! +! nPar unsigned int(8 bit) - Number of Parameters ! +! ! +! file_extension char* - File extension associated ! +! with the numerical dataset. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! bwc_data* - Structure used to store a numerical ! +! dataset/compressed bitstream. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 09.06.2021 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +bwc_data* +bwc_initialize_data(double* field, uint64 const nX, uint64 const nY, uint64 const nZ, uint16 const nTS, uint8 const nPar, char *file_extension) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_inf *info; + bwc_data *file; + + file = calloc(1, sizeof(bwc_data)); + if(!file) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return NULL; + } + + info = &file->info; + + info->nX = nX; + info->nY = nY; + info->nZ = nZ; + info->nTS = nTS; + info->nPar = nPar; + memcpy(&info->f_ext, file_extension, sizeof(char) * 19); + + file->field.d = field; + + return file; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_add_param(bwc_data* data, char *name, uint16 sample, uchar dim, uint8 precision) ! +! -------------- ! +! ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function initializes and adds new parameters to the parameter linked list. The linked ! +! list stores the parameter name, its precision, sampling factor and the dimension for which ! +! the sampling is active. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! name char* - Name of parameter(id). ! +! ! +! sample unsigned int(16 bit) - Sampling factor for parameter(id). ! +! ! +! dim unsigned char - Dimension(s) for which the sampling ! +! factor is active. ! +! ! +! precision unsigned int(8 bit) - Bit precision of the parameter. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.10.2017 Patrick Vogler B87D120 V 0.1.0 function created ! +! 03.12.2019 Patrick Vogler B87E7E4 V 0.1.0 redefined the function for the ! +! bwc_data structure. ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_add_param(bwc_data* data, char *name, uint16 sample, uchar dim, uint8 precision) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_inf *info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(data); + assert(dim <= DIM_ALL); + + /*--------------------------------------------------------*\ + ! Save the global info structure to a temporary variable ! + ! to make the code more readable. ! + \*--------------------------------------------------------*/ + info = &data->info; + + /*--------------------------------------------------------*\ + ! Check if the specified parameter name has the proper ! + ! length. ! + \*--------------------------------------------------------*/ + if((strlen(name) > 24) && name) + { + fprintf(stderr, "o==========================================================o\n"\ + "| WARNING: Invalid parameter name: %-24s|\n"\ + "| |\n"\ + "| Parameter names cannot exceed 24 characters. |\n"\ + "| |\n"\ + "o==========================================================o\n",name); + } + + /*--------------------------------------------------------*\ + ! Check if the parameter structure has already been allo- ! + ! cated. ! + \*--------------------------------------------------------*/ + if(info->parameter == NULL) + { + /*--------------------------------------------------------*\ + ! If the bwc_add_param function is called for the first ! + ! time, allocate the parameter structure and save the root ! + ! node address. ! + \*--------------------------------------------------------*/ + info->parameter = calloc(1, sizeof(bwc_cmd_opts_ll)); + info->parameter->root = info->parameter; + } + else + { + /*--------------------------------------------------------*\ + ! If a new parameter is added, allocate the nex linked ! + ! list node, save the root node address in its structure ! + ! and set the linked list access pointer to the new node. ! + \*--------------------------------------------------------*/ + info->parameter->next = calloc(1, sizeof(bwc_cmd_opts_ll)); + info->parameter->next->root = info->parameter->root; + info->parameter->next->id = info->parameter->id + 1; + info->parameter = info->parameter->next; + } + + /*--------------------------------------------------------*\ + ! Save the name of the new parameter, its sampling value, ! + ! the dimension for which the sampling is active and the ! + ! the parameters index in the structure of the new node. ! + \*--------------------------------------------------------*/ + strcpy(info->parameter->name, name ? name : "undefined"); + info->parameter->sample = (sample < 64) ? sample : 0; + info->parameter->dim = dim ? dim : (DIM_X | DIM_Y | DIM_Z); + info->parameter->precision = precision ? precision : PREC_BYTE; + + /*--------------------------------------------------------*\ + ! Evaluate the parameter size after sub-sampling and safe ! + ! the information in the linked list. ! + \*--------------------------------------------------------*/ + info->parameter->size = (info->nX >> ((dim & DIM_X) ? sample : 0)) * + (info->nY >> ((dim & DIM_Y) ? sample : 0)) * + (info->nZ >> ((dim & DIM_Z) ? sample : 0)) * + (info->nTS >> ((dim & DIM_TS) ? sample : 0)); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: bwc_field *bwc_initialize_data(...) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to copy the numerical dataset stored in the bwc_data ! +! structure to a user supplied memory block. A size argument is necessary ! +! to verify that the memory block has the correct size. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! data bwc_data* - Structure used to store a numerical ! +! dataset/compressed bitstream. ! +! ! +! buffer unsigned char* - Memory block supplied by ! +! the function caller. ! +! ! +! data bwc_data* - Size of memory block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 09.06.2021 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_get_data(bwc_data* data, uchar* buffer, uint64 size) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_inf *info; + + info = &data->info; + + if(size != (uint64)(data->info.nX * data->info.nY * data->info.nZ * data->info.nTS * data->info.nPar)) + { + fprintf(stderr, "Incorrect buffer size\n"); + } + else + { + memcpy(buffer, data->field.d, size * sizeof(double)); + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_free_data(bwc_data* file) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function deallocates the data structure used to store an numerical dataset/compressed ! +! and can be called if an error occurs or once the data is no longer needed is to be closed. ! +! The deallocation will be carried out down to the structure levels that have been allocated. ! +! ! +! PARAMETERS: ! +! ----------- ! +! ! +! Variable Type Description ! +! -------- ---- ----------- ! +! file bwc_data - Defines a structure used to store all ! +! the relevant parameters and the data ! +! field of a numerical dataset or com- ! +! pressed codestream. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! 04.12.2019 Patrick Vogler B87E7E4 V 0.1.0 +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_free_data(bwc_data* data) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_cmd_opts_ll *param, *temp; + + if(data) + { + if(data->info.parameter) + { + param = data->info.parameter->root; + + while(param != NULL) + { + temp = param; + param = param -> next; + free(temp); + } + } + + if(data) + { + if(data->codestream.data) + { + release_packed_stream(data->codestream.data); + } + if(data->codestream.aux) + { + release_packed_stream(data->codestream.aux); + } + if(data->codestream.com) + { + release_packed_stream(data->codestream.com); + } + if(data->file.fp) + { + fclose(data->file.fp); + } + free(data->codestream.data); + free(data->codestream.aux); + free(data->codestream.com); + free(data->file.d_root); + free(data->file.f_root); + free(data->field.d); + free(data->field.f); + free(data); + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar create_field(bwc_field *const field) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function creates the field structure used to (de)compress a floating point array de- ! +! fined by the bwc_initialize function. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +create_field(bwc_field *const field) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 cblk, nPackets; + uint32 num_tiles_X, num_tiles_Y, num_tiles_Z, num_tiles_TS; + uint32 c, i, p, t, x, y, z; + uint32 max_Prec; + int16 r; + uint8 j; + int8 l,m, n; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar highband_flag = 0; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + bwc_cmd_opts_ll *param; + bwc_parameter *parameter; + bwc_param_ctrl *param_control; + bwc_param_inf *param_info; + bwc_packet *packet; + bwc_resolution *resolution; + bwc_res_ctrl *res_control; + bwc_res_inf *res_info; + bwc_tile *tile; + bwc_tile_ctrl *tile_control; + bwc_tile_inf *tile_info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = field->info; + + /*--------------------------------------------------------*\ + ! Calculate the number of tiles in all spatial and tempo- ! + ! ral directions and allocate the tile structure accord- ! + ! ingly. ! + \*--------------------------------------------------------*/ + num_tiles_X = (int)ceil(((float)info->nX / control->tileSizeX)); + num_tiles_Y = (int)ceil(((float)info->nY / control->tileSizeY)); + num_tiles_Z = (int)ceil(((float)info->nZ / control->tileSizeZ)); + num_tiles_TS = (int)ceil(((float)info->nTS/ control->tileSizeTS)); + + field->tile = calloc(control->nTiles, sizeof(bwc_tile)); + if(!field->tile) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Walk through and setup the tile structure according to ! + ! the specified compression parameters. ! + \*--------------------------------------------------------*/ + for(t = 0, i = 0; t < num_tiles_TS; ++t) + { + for(z = 0; z < num_tiles_Z; ++z) + { + for(y = 0; y < num_tiles_Y; ++y) + { + for(x = 0; x < num_tiles_X; ++x, ++i) + { + /*--------------------------------------------------------*\ + ! Initialize the number of packets and maximum number of ! + ! precincts variables. ! + \*--------------------------------------------------------*/ + nPackets = 0; + max_Prec = 0; + + /*--------------------------------------------------------*\ + ! Save the tile and its info and control structure to tem- ! + ! porary variables to make the code more readable. ! + \*--------------------------------------------------------*/ + tile = &field->tile[i]; + tile_control = &tile->control; + tile_info = &tile->info; + + /*--------------------------------------------------------*\ + ! Save the index for the current tile. ! + \*--------------------------------------------------------*/ + tile_info->tile_index = i; + + /*--------------------------------------------------------*\ + ! Calculate the boundaries for the current tile. ! + \*--------------------------------------------------------*/ + tile_info->X0 = (uint64)MAX(0, x * control->tileSizeX); + tile_info->Y0 = (uint64)MAX(0, y * control->tileSizeY); + tile_info->Z0 = (uint64)MAX(0, z * control->tileSizeZ); + tile_info->TS0 = (uint16)MAX(0, t * control->tileSizeTS); + tile_info->X1 = (uint64)MIN(info->nX , (x + 1) * control->tileSizeX); + tile_info->Y1 = (uint64)MIN(info->nY , (y + 1) * control->tileSizeY); + tile_info->Z1 = (uint64)MIN(info->nZ , (z + 1) * control->tileSizeZ); + tile_info->TS1 = (uint16)MIN(info->nTS, (t + 1) * control->tileSizeTS); + + /*--------------------------------------------------------*\ + ! Initialize the tile header size. ! + \*--------------------------------------------------------*/ + tile_control->header_size = 14; + + /*--------------------------------------------------------*\ + ! Initialize the convex hull slope threshold. ! + \*--------------------------------------------------------*/ + tile_control->slope_max = 0x0000; + tile_control->slope_min = 0xFFFF; + + /*--------------------------------------------------------*\ + ! Allocate, walk through and setup the parameter structure ! + ! according to the specified compression parameters. ! + \*--------------------------------------------------------*/ + tile->parameter = calloc(info->nPar, sizeof(bwc_parameter)); + if(!tile->parameter) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Initialize the parameter information linked listed. ! + \*--------------------------------------------------------*/ + param = info->parameter->root; + + for(j = 0; j < info->nPar; ++j) + { + /*--------------------------------------------------------*\ + ! Check if there is a node in the parameter information ! + ! linked list corresponding to the current paramter. ! + \*--------------------------------------------------------*/ + if(!param && (param->id == j)) + { + fprintf(stderr, MEMERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Save the parameter and its info and control structure to ! + ! temporary variables to make the code more readable. ! + \*--------------------------------------------------------*/ + parameter = &tile->parameter[j]; + param_control = ¶meter->control; + param_info = ¶meter->info; + + /*--------------------------------------------------------*\ + ! Save the corresponding parameter name and its sampling ! + ! factors and precision in the info and control structures.! + \*--------------------------------------------------------*/ + param_info->name = param->name; + param_info->precision = param->precision; + + param_control->sampX = (param->dim & 1) ? param->sample : 0; + param_control->sampY = (param->dim & 2) ? param->sample : 0; + param_control->sampZ = (param->dim & 4) ? param->sample : 0; + param_control->sampTS = (param->dim & 8) ? param->sample : 0; + + /*--------------------------------------------------------*\ + ! Initialize the number of codeblocks for the current ! + ! parameter. ! + \*--------------------------------------------------------*/ + param_control->number_of_codeblocks = 0; + cblk = 0; + + /*--------------------------------------------------------*\ + ! Initialize the maximum and minimum parameter value in ! + ! the parameter structure. ! + \*--------------------------------------------------------*/ + param_info->parameter_max = -FLT_MAX; + param_info->parameter_min = FLT_MAX; + + /*--------------------------------------------------------*\ + ! Calculate the boundaries for the current parmeter ac- ! + ! cording to equation (11.4) from JPEG2000 by David S. ! + ! Taubman and Michael W. Marcellin (p.454). ! + \*--------------------------------------------------------*/ + param_info->X0 = (uint64)ceil((float)tile->info.X0 / (1 << parameter->control.sampX)); + param_info->Y0 = (uint64)ceil((float)tile->info.Y0 / (1 << parameter->control.sampY)); + param_info->Z0 = (uint64)ceil((float)tile->info.Z0 / (1 << parameter->control.sampZ)); + param_info->TS0 = (uint16)ceil((float)tile->info.TS0/ (1 << parameter->control.sampTS)); + param_info->X1 = (uint64)ceil((float)tile->info.X1 / (1 << parameter->control.sampX)); + param_info->Y1 = (uint64)ceil((float)tile->info.Y1 / (1 << parameter->control.sampY)); + param_info->Z1 = (uint64)ceil((float)tile->info.Z1 / (1 << parameter->control.sampZ)); + param_info->TS1 = (uint16)ceil((float)tile->info.TS1/ (1 << parameter->control.sampTS)); + + /*--------------------------------------------------------*\ + ! Allocate, walk through and setup the resolution struc- ! + ! ture according to the specified compression parameters. ! + \*--------------------------------------------------------*/ + parameter->resolution = calloc(control->nDecomp + 1, sizeof(bwc_resolution)); + if(!parameter->resolution) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + for(r = 0; r < control->nDecomp + 1; ++r) + { + /*--------------------------------------------------------*\ + ! Save the resolution and its info and control structure ! + ! to temporary variables to make the code more readable. ! + \*--------------------------------------------------------*/ + resolution = ¶meter->resolution[r]; + res_control = &resolution->control; + res_info = &resolution->info; + + /*--------------------------------------------------------*\ + ! Calculate the boundaries for the current resolution ac- ! + ! cording to the corresponding equation from JPEG2000 by ! + ! David S. Taubman and Michael W. Marcellin (p.456). ! + \*--------------------------------------------------------*/ + res_info->X0 = (uint64)ceil((float)param_info->X0 / (1 << MIN(control->nDecomp -r, control->decompX))); + res_info->Y0 = (uint64)ceil((float)param_info->Y0 / (1 << MIN(control->nDecomp -r, control->decompY))); + res_info->Z0 = (uint64)ceil((float)param_info->Z0 / (1 << MIN(control->nDecomp -r, control->decompZ))); + res_info->TS0 = (uint16)ceil((float)param_info->TS0/ (1 << MIN(control->nDecomp -r, control->decompTS))); + res_info->X1 = (uint64)ceil((float)param_info->X1 / (1 << MIN(control->nDecomp -r, control->decompX))); + res_info->Y1 = (uint64)ceil((float)param_info->Y1 / (1 << MIN(control->nDecomp -r, control->decompY))); + res_info->Z1 = (uint64)ceil((float)param_info->Z1 / (1 << MIN(control->nDecomp -r, control->decompZ))); + res_info->TS1 = (uint16)ceil((float)param_info->TS1/ (1 << MIN(control->nDecomp -r, control->decompTS))); + + /*--------------------------------------------------------*\ + ! Calculate the number of precincts to cover tile t in pa- ! + ! rameter p at resolution r according to equation (11.10) ! + ! from JPEG2000 by D. S. Taubman and M. W. Marcellin ! + ! (p.459). ! + \*--------------------------------------------------------*/ + res_control->numPX = (uint16)((res_info->X0 == res_info->X1) ? 0 : (ceil((float)res_info->X1 / (1 << control->precSizeX) + - floor((float)res_info->X0 / (1 << control->precSizeX))))); + res_control->numPY = (uint16)((res_info->Y0 == res_info->Y1) ? 0 : (ceil((float)res_info->Y1 / (1 << control->precSizeY) + - floor((float)res_info->Y0 / (1 << control->precSizeY))))); + res_control->numPZ = (uint16)((res_info->Z0 == res_info->Z1) ? 0 : (ceil((float)res_info->Z1 / (1 << control->precSizeZ) + - floor((float)res_info->Z0 / (1 << control->precSizeZ))))); + res_control->numPTS = (uint16)((res_info->TS0 == res_info->TS1) ? 0 : (ceil((float)res_info->TS1 / (1 << control->precSizeTS) + - floor((float)res_info->TS0 / (1 << control->precSizeTS))))); + + res_control->number_of_precincts = (uint64)res_control->numPX * res_control->numPY * res_control->numPZ * res_control->numPTS; + + /*--------------------------------------------------------*\ + ! Add up the global number of packets and evaluate the ! + ! maximum number of precincts between all resolution lev- ! + ! els for all tile parameters. ! + \*--------------------------------------------------------*/ + nPackets += (res_control->number_of_precincts * control->nLayers); + max_Prec = MAX(res_control->number_of_precincts * control->nLayers, max_Prec); + + /*--------------------------------------------------------*\ + ! Calculate and save the real codeblock size in the reso- ! + ! lution control structure. ! + \*--------------------------------------------------------*/ + if(r == 0) + { + res_control->rcbX = MIN(control->cbX, (uint8)(control->precSizeX)); + res_control->rcbY = MIN(control->cbY, (uint8)(control->precSizeY)); + res_control->rcbZ = MIN(control->cbZ, (uint8)(control->precSizeZ)); + res_control->rcbTS = MIN(control->cbTS, (uint8)(control->precSizeTS)); + } + else + { + res_control->rcbX = MIN(control->cbX, (uint8)(control->precSizeX - 1)); + res_control->rcbY = MIN(control->cbY, (uint8)(control->precSizeY - 1)); + res_control->rcbZ = MIN(control->cbZ, (uint8)(control->precSizeZ - 1)); + res_control->rcbTS = MIN(control->cbTS, (uint8)(control->precSizeTS - 1)); + } + + /*--------------------------------------------------------*\ + ! Evaluate in which spatial or temporal directions the ! + ! wavelet decomposition has been applied to according to ! + ! the current resolution level and amend the highband flag ! + ! accordingly. ! + \*--------------------------------------------------------*/ + highband_flag = (control->nDecomp - control->decompX < r && r > 0) ? DIM_X : 0; + highband_flag |= (control->nDecomp - control->decompY < r && r > 0) ? DIM_Y : 0; + highband_flag |= (control->nDecomp - control->decompZ < r && r > 0) ? DIM_Z : 0; + highband_flag |= (control->nDecomp - control->decompTS < r && r > 0) ? DIM_TS : 0; + + /*--------------------------------------------------------*\ + ! Evaluate the overall number of subbands, for the current ! + ! resolution level, according to the value of the highband ! + ! flag. ! + \*--------------------------------------------------------*/ + res_control->number_of_subbands = (1 << (((highband_flag & DIM_X)) + + ((highband_flag & DIM_Y) >> 1) + + ((highband_flag & DIM_Z) >> 2) + + ((highband_flag & DIM_TS) >> 3))); + + res_control->number_of_subbands -= (res_control->number_of_subbands & 1) ? 0 : 1; + + /*--------------------------------------------------------*\ + ! Allocate the point array used to hold the memory handles ! + ! of all packets created for the current resolution. ! + \*--------------------------------------------------------*/ + resolution->packet = calloc(res_control->number_of_precincts * control->nLayers, sizeof(bwc_packet)); + if(!resolution->packet) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Allocate, walk through and setup the subband structure ! + ! according to the specified compression parameters. ! + \*--------------------------------------------------------*/ + resolution->subband = calloc(res_control->number_of_subbands, sizeof(bwc_subband)); + if(!resolution->subband) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + for(l = 0, m = 0; m < res_control->number_of_subbands; ++l) + { + if(r == 0 || ((l & highband_flag) == l && l != 0)) + { + if(initialize_subband(field, parameter, resolution, &resolution->subband[m], r, l)) + { + return 1; + } + + /*--------------------------------------------------------*\ + ! Adjust the size of the codeblock access array. ! + \*--------------------------------------------------------*/ + parameter->access = realloc(parameter->access, param_control->number_of_codeblocks * + sizeof(bwc_cblk_access)); + + /*--------------------------------------------------------*\ + ! Fill the codeblock access array with the appropriate ! + ! pointers for the newly initialized precinct, subband and ! + ! codeblock structures. Save the codeblock index with re- ! + ! gards to the current precinct in the codeblock info ! + ! structure. Initialize the packet structure with the indi-! + ! ces for the parameter, resolution, precinct and quality ! + ! layer the packet occupies. ! + \*--------------------------------------------------------*/ + for(p = 0; p < res_control->number_of_precincts; ++p) + { + for(c = 0; c < resolution->subband[m].precinct[p].control.number_of_codeblocks; ++c, ++cblk) + { + parameter->access[cblk].subband = &resolution->subband[m]; + parameter->access[cblk].precinct = &resolution->subband[m].precinct[p]; + parameter->access[cblk].codeblock = &resolution->subband[m].precinct[p].codeblock[c]; + + parameter->access[cblk].codeblock->info.idx = c; + + for(n = 0; n < control->nLayers; ++n) + { + packet = &resolution->packet[n * res_control->number_of_precincts + p]; + + packet->c = j; + packet->r = r; + packet->p = p; + packet->l = n; + } + } + } + m++; + } + } + } + + /*--------------------------------------------------------*\ + ! Advance the parameter information linked listed to the ! + ! next node. ! + \*--------------------------------------------------------*/ + param = param->next; + } + + /*--------------------------------------------------------*\ + ! Allocate the pointer array used to sequence the code- ! + ! stream packets. ! + \*--------------------------------------------------------*/ + tile->packet_sequence = calloc(nPackets, sizeof(bwc_packet*)); + if(!tile->packet_sequence) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Adjust the tile header size if the error resilience op- ! + ! tion has been specified and save the nPackets variable. ! + ! Store the maximum number of Precincts between all reso- ! + ! lution levels in the tile control structure. ! + \*--------------------------------------------------------*/ + tile_control->header_size += control->error_resilience ? 8 * nPackets : 0; + tile_control->nPackets = nPackets; + tile_control->max_Prec = max_Prec; + } + } + } + } + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void kill_compression(bwc_field *const field) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function deallocates the compression field structure used to define and control the ! +! bwc codec and can be called if an error occurs during the (de-)compression stage or once ! +! the codec has finished. The deallocation will be carried out down to the structure levels ! +! that have been allocated. ! +! ! +! PARAMETERS: ! +! ----------- ! +! ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.10.2017 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_kill_compression(bwc_field *const field) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 c, k; + uint32 i; + uint16 j, r; + int8 l; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + if(field) + { + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = field->info; + + if(field->tile) + { + for(i = 0; i < control->nTiles; ++i) + { + if(field->tile[i].parameter) + { + for(j = 0; j < info->nPar; ++j) + { + if(field->tile[i].parameter[j].resolution) + { + for(r = 0; r < control->nDecomp + 1; ++r) + { + if(field->tile[i].parameter[j].resolution[r].subband) + { + for(l = 0; l < field->tile[i].parameter[j].resolution[r].control.number_of_subbands; ++l) + { + if(field->tile[i].parameter[j].resolution[r].subband[l].precinct) + { + for(k = 0; k < field->tile[i].parameter[j].resolution[r].control.number_of_precincts; ++k) + { + if(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock) + { + for(c = 0; c < field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].control.number_of_codeblocks; ++c) + { + if(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock[c].encoded_block) + { + free(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock[c].encoded_block->data); + } + free(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock[c].control.memory); + free(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock[c].encoded_block); + } + } + if(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].control.number_of_codeblocks) + { + kill_tagtree(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].control.tag_inclusion); + kill_tagtree(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].control.tag_msbs); + } + free(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock); + } + } + free(field->tile[i].parameter[j].resolution[r].subband[l].precinct); + } + } + free(field->tile[i].parameter[j].resolution[r].subband); + free(field->tile[i].parameter[j].resolution[r].packet); + } + } + free(field->tile[i].parameter[j].resolution); + free(field->tile[i].parameter[j].access); + } + } + free(field->tile[i].packet_sequence); + free(field->tile[i].parameter); + } + } + free(control->header.memory); + free(control->bitrate); + free(field->tile); + free(field); + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: bwc_field *bwc_initialize_field(bwc_data *const data) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function initializes the bwc_field structure with all necessary standard parameters ! +! to (de)compress a floating point array with nX * nY * nZ grid points, nTS timesteps and ! +! nPar parameters. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! nX ,nY, nZ unsigned int(64 bit) - Structure used to store a numerical ! +! dataset/compressed bitstream. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! bwc_field* Defines the (de)compression data structure. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +bwc_field* +bwc_initialize_field(bwc_data *const data) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint8 levelsX, levelsY, levelsZ; + uint8 levelsTS; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + bwc_float delta; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + /*--------------------------------------------------------*\ + ! Allocate the root compression data structure. ! + \*--------------------------------------------------------*/ + bwc_field *field = calloc(1, sizeof(bwc_field)); + if(!field) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_kill_compression(field); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = field->info = &data->info; + + /*--------------------------------------------------------*\ + ! Set all tile sizes to their maximum allowable value. The ! + ! value for the number of tiles is set to 1. ! + \*--------------------------------------------------------*/ + control->tileSizeX = info->nX; + control->tileSizeY = info->nY; + control->tileSizeZ = info->nZ; + control->tileSizeTS = info->nTS; + control->nTiles = 1; + + /*--------------------------------------------------------*\ + ! Set the spatial and temporal precinct sizes to their ! + ! standard values. For all valid dimensions the values ! + ! are set to 15 while all invalid dimensions are set to ! + ! 0. ! + \*--------------------------------------------------------*/ + control->precSizeX = (info->nX >> 1) ? 15 : 0; + control->precSizeY = (info->nY >> 1) ? 15 : 0; + control->precSizeZ = (info->nZ >> 1) ? 15 : 0; + control->precSizeTS = (info->nTS >> 1) ? 15 : 0; + + /*--------------------------------------------------------*\ + ! Set the spatial and temporal codeblock sizes to their ! + ! standard values. For all valid dimensions the values ! + ! are set to 4 while all invalid dimensions are set to ! + ! 0. ! + \*--------------------------------------------------------*/ + control->cbX = (info->nX >> 1) ? 5 : 0; + control->cbY = (info->nY >> 1) ? 5 : 0; + control->cbZ = (info->nZ >> 1) ? 5 : 0; + control->cbTS = (info->nTS >> 1) ? 5 : 0; + + /*--------------------------------------------------------*\ + ! Set the spatial and temporal wavelet kernels to their ! + ! standard values. ! + \*--------------------------------------------------------*/ + control->KernelX = + control->KernelY = + control->KernelZ = + control->KernelTS = bwc_dwt_9_7; + + /*--------------------------------------------------------*\ + ! Set the progression order, quantization style, number of ! + ! layers, Q number format value and guard bits to their ! + ! standard values. Amend the quantization style default ! + ! parameter for the main header, accordingly. ! + \*--------------------------------------------------------*/ + control->progression = bwc_prog_LRCP; + control->quantization_style = bwc_qt_derived; + control->nLayers = 0x00; + control->Qm = PREC_BIT - 1; + control->bitrate = 0; + control->guard_bits = 2; + + /*--------------------------------------------------------*\ + ! Save the codec precision in the info structure. ! + \*--------------------------------------------------------*/ + info->precision = PREC_BYTE; + + /*--------------------------------------------------------*\ + ! Initialize the number of threads used for the current ! + ! run. ! + \*--------------------------------------------------------*/ + #ifdef _OPENMP + control->nThreads = 1; + #endif + + /*--------------------------------------------------------*\ + ! Calculate the possible decomposition levels for all ! + ! spatial and temporal dimensions. ! + \*--------------------------------------------------------*/ + levelsX = log(info->nX) /log(2); + levelsY = log(info->nY) /log(2); + levelsZ = log(info->nZ) /log(2); + levelsTS = log(info->nTS)/log(2); + + /*--------------------------------------------------------*\ + ! Check if the decomposition levels are specified for a ! + ! valid spatial or temporal dimension. For all invalid and ! + ! unspecified (NULL) values the corresponding decomposi- ! + ! tion level is set to 0. For all valid dimensions the ! + ! number of decomposition levels is set accordingly. ! + \*--------------------------------------------------------*/ + control->decompX = (info->nX >> 1) ? ((4 < levelsX) ? 4 : levelsX) : 0; + control->decompY = (info->nY >> 1) ? ((4 < levelsY) ? 4 : levelsY) : 0; + control->decompZ = (info->nZ >> 1) ? ((4 < levelsZ) ? 4 : levelsZ) : 0; + control->decompTS = (info->nTS >> 1) ? ((4 < levelsTS) ? 4 : levelsTS) : 0; + + control->nDecomp = MAX(control->decompX, + MAX(control->decompY, + MAX(control->decompZ, control->decompTS))); + + /*--------------------------------------------------------*\ + ! Initialize the lookup tables used to calculate the ener- ! + ! gy gain for the multi dimensional wavelet transforms. ! + \*--------------------------------------------------------*/ + if(initialize_gain_lut()) + { + bwc_kill_compression(field); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Calculate the appropriate quantization step size for the ! + ! given number of decomposition levels according to equa- ! + ! tion (10.19) (epsilon = 6, mu = 16) from JPEG2000 by ! + ! by David S. Taubman and Michael W. Marcellin (p.437). ! + \*--------------------------------------------------------*/ + delta = (bwc_float)(1/(pow(2, 2 + PREC_BIT) * sqrt(get_dwt_energy_gain(field, 0, control->nDecomp)))); + + for(control->qt_exponent = 0; delta < 1; ++control->qt_exponent, delta *= 2); + control->qt_mantissa = (uint16)floor(0.5f + ((delta - 1.0f) * (1 << 16))); + + if(control->qt_exponent > PREC_BIT) + { + control->qt_exponent = PREC_BIT; + control->qt_mantissa = 0; + } + if(control->qt_mantissa >= 1 << 16) + { + if(control->qt_exponent == 0) + { + control->qt_exponent = 0; + control->qt_mantissa = (1 << 16) - 1; + } + else + { + control->qt_exponent--; + control->qt_mantissa = 0; + } + } + + return field; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_set_error_resilience(bwc_field *const field) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function sets the error resilience marker in the bwc_field structure if an error ! +! resilient compression approach is to be employed. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 13.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_set_error_resilience(bwc_field *const field) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global control structure to a temporary varia- ! + ! ble to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Amend the codeblock style in the bwc_field structure ! + ! according to the specified value. ! + \*--------------------------------------------------------*/ + control->error_resilience ^= 0x01; + + /*--------------------------------------------------------*\ + ! Record the setting of the error resilience marker in the ! + ! CSsgc variable. ! + \*--------------------------------------------------------*/ + control->CSsgc ^= (0x01 << 0); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_set_quantization_style(bwc_field *const field, bwc_quant_st quantization_style) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the quantization style in the bwc_field structure according to the ! +! specified value. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! quantization_style bwc_quant_st - Quantization style used during compres- ! +! sion. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_set_quantization_style(bwc_field *const field, bwc_quant_st quantization_style) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert((quantization_style == bwc_qt_derived) || (quantization_style == bwc_qt_none)); + + /*--------------------------------------------------------*\ + ! Save the global control structure to a temporary varia- ! + ! ble to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Amend the quantization style in the bwc_field structure ! + ! according to the specified value. ! + \*--------------------------------------------------------*/ + control->quantization_style = quantization_style; + + /*--------------------------------------------------------*\ + ! Record the setting of the quantization style marker in ! + ! the CSsgc variable. ! + \*--------------------------------------------------------*/ + control->CSsgc |= (0x01 << 1); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_set_quantization_step_size(bwc_field *const field, double delta) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the quantization step size in the bwc_field structure according to ! +! the specified value. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! delta double - Quantization step size used during ! +! compression. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 16.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_set_quantization_step_size(bwc_field *const field, double delta) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global control structure to a temporary varia- ! + ! ble to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Check if the quantization step size lies within the ac- ! + ! ceptable range. ! + \*--------------------------------------------------------*/ + if((delta <= 0) || (delta >= 2)) + { + fprintf(stderr, "o==========================================================o\n"\ + "| WARNING: Invalid quantization step size |\n"\ + "| |\n"\ + "| The quantization step size does not lie within |\n"\ + "| the acceptable range of: |\n"\ + "| |\n"\ + "| 0 < step size < 2 |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + return; + } + + /*--------------------------------------------------------*\ + ! Reevaluate the mantissa and exponent of the user defined ! + ! quantization step size. ! + \*--------------------------------------------------------*/ + for(control->qt_exponent = 0; delta < 1; ++control->qt_exponent, delta *= 2); + control->qt_mantissa = (uint16)floor(0.5f + ((delta - 1.0f) * (1 << 16))); + + if(control->qt_exponent > PREC_BIT) + { + control->qt_exponent = PREC_BIT; + control->qt_mantissa = 0; + } + if(control->qt_mantissa >= 1 << 16) + { + if(control->qt_exponent == 0) + { + control->qt_exponent = 0; + control->qt_mantissa = (1 << 16) - 1; + } + else + { + control->qt_exponent--; + control->qt_mantissa = 0; + } + } + + /*--------------------------------------------------------*\ + ! Record the setting of the quantization step size in the ! + ! CSsgc variable. ! + \*--------------------------------------------------------*/ + control->CSsgc |= (0x01 << 2); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_set_progression(bwc_field *const field, bwc_prog_ord progression) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the progression order in the bwc_field structure according to the ! +! specified value. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! progression bwc_prog_ord - Progression orders employed during com- ! +! pression (CPRL, LRCP, PCRL, RLCP, ! +! RPCL). ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_set_progression(bwc_field *const field, bwc_prog_ord progression) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert((progression == bwc_prog_CPRL) || (progression == bwc_prog_LRCP) || + (progression == bwc_prog_PCRL) || (progression == bwc_prog_RLCP) || + (progression == bwc_prog_RPCL)); + + /*--------------------------------------------------------*\ + ! Save the global control structure to a temporary varia- ! + ! ble to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Amend the progression order in the bwc_field structure ! + ! according to the specified value. ! + \*--------------------------------------------------------*/ + control->progression = progression; + + /*--------------------------------------------------------*\ + ! Record the setting of the progression order marker in ! + ! the CSsgc variable. ! + \*--------------------------------------------------------*/ + control->CSsgc |= (0x01 << 3); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_set_kernels(bwc_field *const field, bwc_dwt_filter KernelX, ! +! -------------- bwc_dwt_filter KernelY, ! +! bwc_dwt_filter KernelZ, ! +! bwc_dwt_filter KernelTS) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the wavelet kernels in the bwc_field structure according to the ! +! specified values. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! KernelX, KernelY, KernelZ bwc_dwt_filter - Wavelet kernels used for spatial ! +! decomposition. ! +! ! +! KernelT bwc_dwt_filter - Wavelet kernel used for temporal ! +! decomposition. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_set_kernels(bwc_field *const field, bwc_dwt_filter KernelX, bwc_dwt_filter KernelY, + bwc_dwt_filter KernelZ, bwc_dwt_filter KernelTS) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global control structure to a temporary varia- ! + ! ble to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Amend the wavelet kernels in the bwc_field structure ac- ! + ! cording to the specified values. For all unspecified ! + ! (NULL) values the corresponding wavelet kernel is set to ! + ! bwc_dwt_9_7/bwc_dwt_haar. ! + \*--------------------------------------------------------*/ + control->KernelX = KernelX ? KernelX : bwc_dwt_9_7; + control->KernelY = KernelY ? KernelY : bwc_dwt_9_7; + control->KernelZ = KernelZ ? KernelZ : bwc_dwt_9_7; + control->KernelTS = KernelTS ? KernelTS : bwc_dwt_haar; + + /*--------------------------------------------------------*\ + ! Record the setting of the wavelet kernel order markers ! + ! in the CSsgc variable. ! + \*--------------------------------------------------------*/ + control->CSsgc |= (0x01 << 4); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_set_decomp(bwc_field *const field, uint8 decompX, uint8 decompY, ! +! -------------- uint8 decompZ, uint8 decompTS) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the decomposition levels in the bwc_field structure according to the ! +! specified values. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! decompX, decompY, decompZ unsigned int(8 bit) - Number of spatial wavelet decomposition ! +! levels used during compression. ! +! ! +! decompTS unsigned int(8 bit) - Number of temporal wavelet decomposi- ! +! tion level used during compression. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_set_decomp(bwc_field *const field, uint8 decompX, uint8 decompY, uint8 decompZ, uint8 decompTS) +{ + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + double delta; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uint8 levelsX, levelsY, levelsZ, levelsTS; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = field->info; + + /*--------------------------------------------------------*\ + ! Calculate the possible decomposition levels for all ! + ! spatial and temporal dimensions. ! + \*--------------------------------------------------------*/ + levelsX = log(info->nX) /log(2); + levelsY = log(info->nY) /log(2); + levelsZ = log(info->nZ) /log(2); + levelsTS = log(info->nTS)/log(2); + + /*--------------------------------------------------------*\ + ! Check if the decomposition levels are specified for a ! + ! valid spatial or temporal dimension. For all invalid and ! + ! unspecified (NULL) values the corresponding decomposi- ! + ! tion level is set to 0. For all valid dimensions the ! + ! number of decompositions is set accordingly. ! + \*--------------------------------------------------------*/ + control->decompX = (info->nX >> 1) ? ((decompX < levelsX) ? decompX : levelsX) : 0; + control->decompY = (info->nY >> 1) ? ((decompY < levelsY) ? decompY : levelsY) : 0; + control->decompZ = (info->nZ >> 1) ? ((decompZ < levelsZ) ? decompZ : levelsZ) : 0; + control->decompTS = (info->nTS >> 1) ? ((decompTS < levelsTS) ? decompTS : levelsTS) : 0; + + /*--------------------------------------------------------*\ + ! Calculate the overall number of decomposition levels. ! + \*--------------------------------------------------------*/ + control->nDecomp = MAX(control->decompX, + MAX(control->decompY, + MAX(control->decompZ, control->decompTS))); + + /*--------------------------------------------------------*\ + ! Check if the decomposition levels have valid values. ! + \*--------------------------------------------------------*/ + if((control->decompX > 63) || (control->decompY > 63) || + (control->decompZ > 63) || (control->decompTS > 31)) + { + fprintf(stderr, "o==========================================================o\n"\ + "| WARNING: Invalid decomposition level value |\n"\ + "| |\n"\ + "| The maximum acceptable decomposition level is |\n"\ + "| 63 for all spatial and 31 for the temporal |\n"\ + "| dimensions. |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + /*--------------------------------------------------------*\ + ! Reset the decomposition levels to their standard values. ! + \*--------------------------------------------------------*/ + control->decompX = (info->nX >> 1) ? 4 : 0; + control->decompY = (info->nY >> 1) ? 4 : 0; + control->decompZ = (info->nZ >> 1) ? 4 : 0; + control->decompTS = (info->nTS >> 1) ? 4 : 0; + + return; + } + + /*--------------------------------------------------------*\ + ! Initialize the lookup tables used to calculate the ener- ! + ! gy gain for the multi dimensional wavelet transforms. ! + \*--------------------------------------------------------*/ + if(initialize_gain_lut()) + { + bwc_kill_compression(field); + return; + } + + /*--------------------------------------------------------*\ + ! Calculate the appropriate quantization step size for the ! + ! given number of decomposition levels according to equa- ! + ! tion (10.19) (epsilon = 6, mu = 16) from JPEG2000 by ! + ! by David S. Taubman and Michael W. Marcellin (p.437). ! + \*--------------------------------------------------------*/ + delta = 1/(pow(2, 2 + PREC_BIT) * sqrt(get_dwt_energy_gain(field, 0, control->nDecomp))); + + for(control->qt_exponent = 0; delta < 1; ++control->qt_exponent, delta *= 2); + control->qt_mantissa = (uint16)floor(0.5f + ((delta - 1.0f) * (1 << 16))); + + if(control->qt_exponent > PREC_BIT) + { + control->qt_exponent = PREC_BIT; + control->qt_mantissa = 0; + } + if(control->qt_mantissa >= 1 << 16) + { + if(control->qt_exponent == 0) + { + control->qt_exponent = 0; + control->qt_mantissa = (1 << 16) - 1; + } + else + { + control->qt_exponent--; + control->qt_mantissa = 0; + } + } + + /*--------------------------------------------------------*\ + ! Record the setting of the decomposition level variables ! + ! in the CSsgc variable. ! + \*--------------------------------------------------------*/ + control->CSsgc |= (0x01 << 5); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_set_precincts(bwc_field *const field, uint8 pX, uint8 pY, uint8 pZ, uint8 pTS) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the precinct size in the bwc_field structure according to the ! +! specified values. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! px, py, pz, pTS unsigned int(8 bit) - Spatial and temporal precinct dimensions! +! in log2 exponent format. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 15.05.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_set_precincts(bwc_field *const field, uint8 pX, uint8 pY, uint8 pZ, uint8 pTS) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = field->info; + + /*--------------------------------------------------------*\ + ! Check if the precinct sizes are specified for a valid ! + ! spatial or temporal dimension. For all invalid and un- ! + ! specified (NULL) values the corresponding precinct size ! + ! is set to 0. For all valid dimensions the precinct size ! + ! is set accordingly. ! + \*--------------------------------------------------------*/ + control->precSizeX = (info->nX >> 1) ? (pX ? pX : 15) : 0; + control->precSizeY = (info->nY >> 1) ? (pY ? pY : 15) : 0; + control->precSizeZ = (info->nZ >> 1) ? (pZ ? pZ : 15) : 0; + control->precSizeTS = (info->nTS >> 1) ? (pTS ? pTS : 15) : 0; + + /*--------------------------------------------------------*\ + ! Check if the codeblock sizes have valid values. ! + \*--------------------------------------------------------*/ + if(((control->precSizeX < 1) && (info->nX >> 1)) || + ((control->precSizeY < 1) && (info->nY >> 1)) || + ((control->precSizeZ < 1) && (info->nZ >> 1)) || + ((control->precSizeTS < 1) && (info->nTS >> 1)) || + (control->precSizeX > 15) || (control->precSizeY > 15) || (control->precSizeZ > 15) || (control->precSizeTS > 15)) + { + fprintf(stderr, "o==========================================================o\n"\ + "| WARNING: Invalid precinct size |\n"\ + "| |\n"\ + "| The maximum acceptable precinct size is 2^15, |\n"\ + "| the smallest valid precinct size is 2^1. |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + /*--------------------------------------------------------*\ + ! Reset the codeblock sizes to their standard values. ! + \*--------------------------------------------------------*/ + control->precSizeX = (info->nX >> 1) ? 15 : 0; + control->precSizeY = (info->nY >> 1) ? 15 : 0; + control->precSizeZ = (info->nZ >> 1) ? 15 : 0; + control->precSizeTS = (info->nTS >> 1) ? 15 : 0; + + return; + } + + /*--------------------------------------------------------*\ + ! Record the setting of the precinct size variables in the ! + ! CSsgc variable. ! + \*--------------------------------------------------------*/ + control->CSsgc |= (0x01 << 6); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_set_codeblocks(bwc_field *const field, uint8 cbX, uint8 cbY, ! +! -------------- uint8 cbZ, uint8 cbTS) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the codeblock size in the bwc_field structure according to the ! +! specified values. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! cbx, cby, cbz, cbTS unsigned int(8 bit) - Spatial and temporal codeblock dimen- ! +! sions in log2 exponent format. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_set_codeblocks(bwc_field *const field, uint8 cbX, uint8 cbY, uint8 cbZ, uint8 cbTS) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = field->info; + + /*--------------------------------------------------------*\ + ! Check if the codeblock sizes are specified for a valid ! + ! spatial or temporal dimension. For all invalid and un- ! + ! specified (NULL) values the corresponding codeblock size ! + ! is set to 0. For all valid dimensions the codeblock size ! + ! is set accordingly. ! + \*--------------------------------------------------------*/ + control->cbX = (info->nX >> 1) ? (cbX ? cbX : 5) : 0; + control->cbY = (info->nY >> 1) ? (cbY ? cbY : 5) : 0; + control->cbZ = (info->nZ >> 1) ? (cbZ ? cbZ : 5) : 0; + control->cbTS = (info->nTS >> 1) ? (cbTS ? cbTS : 5) : 0; + + /*--------------------------------------------------------*\ + ! Check if the codeblock sizes have valid values. ! + \*--------------------------------------------------------*/ + if((control->cbX > 10) || (control->cbY > 10) || (control->cbZ > 10) || (control->cbTS > 10)|| + ((control->cbX + control->cbY + control->cbZ + control->cbTS) < 4) || + ((control->cbX + control->cbY + control->cbZ + control->cbTS) > 20)) + { + fprintf(stderr, "o==========================================================o\n"\ + "| WARNING: Invalid codeblock size |\n"\ + "| |\n"\ + "| The maximum acceptable codeblock size is 2^20 |\n"\ + "| with a maximum allowable number of datapoints |\n"\ + "| in each dimension of 2^10. The smallest valid |\n"\ + "| codeblock size is 2^4. |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + /*--------------------------------------------------------*\ + ! Reset the codeblock sizes to their standard values. ! + \*--------------------------------------------------------*/ + control->cbX = (info->nX >> 1) ? 5 : 0; + control->cbY = (info->nY >> 1) ? 5 : 0; + control->cbZ = (info->nZ >> 1) ? 5 : 0; + control->cbTS = (info->nTS >> 1) ? 5 : 0; + + return; + } + + /*--------------------------------------------------------*\ + ! Record the setting of the codeblock size variables in ! + ! the CSsgc variable. ! + \*--------------------------------------------------------*/ + control->CSsgc |= (0x01 << 7); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_set_qm(bwc_field *const field, uint8 Qm) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the Q number formate range in the bwc_field structure according to the ! +! specified value. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! Qm unsigned int(8 bit) - Q number formate range (m). ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_set_qm(bwc_field *const field, uint8 Qm) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global control structure to a temporary varia- ! + ! ble to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Check if the Q number formate range is valid and amend ! + ! the bwc_field structure accordingly. ! + \*--------------------------------------------------------*/ + if((int8)(PREC_BIT - Qm) < 2) + { + fprintf(stderr, "o==========================================================o\n"\ + "| WARNING: Invalid Q number formate range |\n"\ + "| |\n"\ + "| The specified Q number formate range is larger |\n"); + #ifdef BWC_SINGLE_PRECISION + fprintf(stderr, "| than the permitted 30 bits. |\n"); + #else + fprintf(stderr, "| than the permitted 62 bits. |\n"); + #endif + fprintf(stderr, "| |\n"\ + "o==========================================================o\n"); + } + else + { + control->Qm = Qm; + + /*--------------------------------------------------------*\ + ! Record the setting of the Q number format range in the ! + ! CSsgc variable. ! + \*--------------------------------------------------------*/ + control->CSsgc |= (0x01 << 8); + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_set_tiles(bwc_field *const field, uint32 tilesX, uint32 tilesY, uint32 tilesZ, ! +! -------------- uint32 tilesTS, uchar instr) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the tileSize and num_Tiles values in the bwc_field structure according ! +! to the specified values. The NUMBEROF and SIZEOF constants can be used to either specify ! +! the tile sizes or the number of tiles in each spatial and temporal directions. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! tilesX, tilesY, tilesZ unsigned int(32 bit) - Variables defining the size of ! +! a spatial tile. ! +! ! +! tilesTS unsigned int(32 bit) - Variables defining the size of ! +! a temporal tile. ! +! ! +! instr bwc_tile_instr - Constants used to instruct the ! +! bwc_set_tiles function. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bwc_set_tiles(bwc_field *const field, uint64 tilesX, uint64 tilesY, uint64 tilesZ, uint16 tilesTS, bwc_tile_instr instr) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 num_tiles_X, num_tiles_Y, num_tiles_Z; + uint16 num_tiles_TS; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(instr == bwc_tile_sizeof || instr == bwc_tile_numbof); + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = field->info; + + /*--------------------------------------------------------*\ + ! Check if the size of one tile or the overall number of ! + ! tiles are defined. ! + \*--------------------------------------------------------*/ + if(instr == bwc_tile_sizeof) + { + /*--------------------------------------------------------*\ + ! Check if the tile sizes have valid values. ! + \*--------------------------------------------------------*/ + if((control->tileSizeX < 16 && control->tileSizeX > info->nX)|| + (control->tileSizeY < 16 && control->tileSizeY > info->nY)|| + (control->tileSizeZ < 16 && control->tileSizeZ > info->nZ)|| + (control->tileSizeTS < 16 && control->tileSizeTS > info->nTS)) + { + fprintf(stderr,"o==========================================================o\n"\ + "| WARNING: Invalid Tile Dimensions |\n"\ + "| |\n"\ + "| One or more of the specified tile dimensions |\n"\ + "| has a value that falls outside of its valid |\n"\ + "| range. Please verify that all tile dimension |\n"\ + "| are within the range of: |\n"\ + "| |\n"\ + "| 16 ≤ Tile_Size_Xi ≤ Grid_Points_Xi |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + return; + } + + /*--------------------------------------------------------*\ + ! Check if the tile dimensions are specified for a valid ! + ! spatial or temporal dimension. All invalid and unspeci- ! + ! fied (NULL) values are set to the maximum allowable tile ! + ! size. ! + \*--------------------------------------------------------*/ + control->tileSizeX = (info->nX >> 1) ? (tilesX ? tilesX : info->nX) : info->nX; + control->tileSizeY = (info->nY >> 1) ? (tilesY ? tilesY : info->nY) : info->nY; + control->tileSizeZ = (info->nZ >> 1) ? (tilesZ ? tilesZ : info->nZ) : info->nZ; + control->tileSizeTS = (info->nTS >> 1) ? (tilesTS ? tilesTS : info->nTS) : info->nTS; + + /*--------------------------------------------------------*\ + ! Calculate the number of tiles in all spatial and tempo- ! + ! ral directions and the overall number of tiles. ! + \*--------------------------------------------------------*/ + num_tiles_X = (uint64)ceil(((float)info->nX / control->tileSizeX)); + num_tiles_Y = (uint64)ceil(((float)info->nY / control->tileSizeY)); + num_tiles_Z = (uint64)ceil(((float)info->nZ / control->tileSizeZ)); + num_tiles_TS = (uint16)ceil(((float)info->nTS/ control->tileSizeTS)); + control->nTiles = num_tiles_X * num_tiles_Y * num_tiles_Z * num_tiles_TS; + + /*--------------------------------------------------------*\ + ! Check if the number of tiles exceeds its maximum allowa- ! + ! ble value. ! + \*--------------------------------------------------------*/ + if(((double)num_tiles_X * num_tiles_Y * num_tiles_Z * num_tiles_TS) > 0xFFFFFFFFFFFFFFFF) + { + fprintf(stderr,"o==========================================================o\n"\ + "| WARNING: Invalid Tile Dimensions |\n"\ + "| |\n"\ + "| The number of tiles exceeds its maxmum allowa- |\n"\ + "| ble value. Please adjust all tile dimension so |\n"\ + "| that the number of tiles falls within the range |\n"\ + "| of: |\n"\ + "| Number_of_Tiles < 2^64 |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + /*--------------------------------------------------------*\ + ! Reset the tile sizes to their standard values. ! + \*--------------------------------------------------------*/ + control->tileSizeX = info->nX; + control->tileSizeY = info->nY; + control->tileSizeZ = info->nZ; + control->tileSizeTS = info->nTS; + + return; + } + } + else if(bwc_tile_numbof) + { + /*--------------------------------------------------------*\ + ! Check if the number of tiles exceeds its maximum allowa- ! + ! ble value. ! + \*--------------------------------------------------------*/ + if(((double)tilesX * tilesY * tilesZ * tilesTS) > 0xFFFFFFFFFFFFFFFF) + { + fprintf(stderr,"o==========================================================o\n"\ + "| WARNING: Invalid Number Of Tiles |\n"\ + "| |\n"\ + "| The number of tiles exceeds its maxmum allowa- |\n"\ + "| ble value of: |\n"\ + "| |\n"\ + "| Number_of_Tiles < 2^64 |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + return; + } + + /*--------------------------------------------------------*\ + ! Check if the number of tiles are specified for a valid ! + ! spatial or temporal dimension. For all invalid and un- ! + ! specified (NULL) values the corresponding tile size is ! + ! set to its maximum allowable value. For all valid values ! + ! the tile sizes are calculated accordingly. ! + \*--------------------------------------------------------*/ + control->tileSizeX = (info->nX >> 1) ? (tilesX ? (uint64)ceil(((float)info->nX / tilesX)) : info->nX) : info->nX; + control->tileSizeY = (info->nY >> 1) ? (tilesY ? (uint64)ceil(((float)info->nY / tilesY)) : info->nY) : info->nY; + control->tileSizeZ = (info->nZ >> 1) ? (tilesZ ? (uint64)ceil(((float)info->nZ / tilesZ)) : info->nZ) : info->nZ; + control->tileSizeTS = (info->nTS >> 1) ? (tilesTS ? (uint16)ceil(((float)info->nTS/ tilesTS)) : info->nTS) : info->nTS; + + /*--------------------------------------------------------*\ + ! Check if the tile sizes have valid values. ! + \*--------------------------------------------------------*/ + if((control->tileSizeX < 16 && control->tileSizeX > info->nX)|| + (control->tileSizeY < 16 && control->tileSizeY > info->nY)|| + (control->tileSizeZ < 16 && control->tileSizeZ > info->nZ)|| + (control->tileSizeTS < 16 && control->tileSizeTS > info->nTS)) + { + fprintf(stderr,"o==========================================================o\n"\ + "| WARNING: Invalid Number Of Tiles |\n"\ + "| |\n"\ + "| One or more of the tile dimensions has a value |\n"\ + "| that falls outside of its valid range. Please |\n"\ + "| verify that the number of tiles for all dimen- |\n"\ + "| sions are set so that the corresponding tile |\n"\ + "| sizes fall within the range of: |\n"\ + "| |\n"\ + "| 16 ≤ Tile_Size_Xi ≤ Grid_Points_Xi |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + /*--------------------------------------------------------*\ + ! Reset the tile sizes to their standard values. ! + \*--------------------------------------------------------*/ + control->tileSizeX = info->nX; + control->tileSizeY = info->nY; + control->tileSizeZ = info->nZ; + control->tileSizeTS = info->nTS; + + return; + } + /*--------------------------------------------------------*\ + ! Reevaluate the number of tiles in all spatial and tempo- ! + ! ral directions and the overall number of tiles. ! + \*--------------------------------------------------------*/ + num_tiles_X = (uint64)ceil(((float)info->nX / control->tileSizeX)); + num_tiles_Y = (uint64)ceil(((float)info->nY / control->tileSizeY)); + num_tiles_Z = (uint64)ceil(((float)info->nZ / control->tileSizeZ)); + num_tiles_TS = (uint16)ceil(((float)info->nTS/ control->tileSizeTS)); + control->nTiles = num_tiles_X * num_tiles_Y * num_tiles_Z * num_tiles_TS; + } + + /*--------------------------------------------------------*\ + ! Record the setting of the tile size variables in the ! + ! CSsgc variable. ! + \*--------------------------------------------------------*/ + control->CSsgc |= (0x01 << 9); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_set_nThreads(bwc_field *const field, uint16 nThreads) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to indicate the maximum number of threads used during ! +! (de)compression. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! nThreads unsigned int(8 bit) - Number of OpenMP threads. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 07.08.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +#if defined(_OPENMP) + void + bwc_set_nThreads(bwc_field *const field, uint8 nThreads) + { + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global control and to a temporary variable to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Amend the number of OMP threads the bwc_field structure. ! + \*--------------------------------------------------------*/ + control->nThreads = nThreads; + } +#endif + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void bwc_create_compression(bwc_field *field, char *rate_control) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function creates the field structure used to compress a floating point array defined ! +! by the bwc_initialize function. For a compression run, the rate_control and instr arguments ! +! need to be passed to the function to properly set up the lossy compression stage. Here, the ! +! instr parameter defines whether rate control is defined by a BITRATE - a floating point val-! +! ue defining the average number of bits per datapoint - and ACCURACY - an integer value de- ! +! fining the exponent of the maximum allowable error (i.e. 15 for err = 1e-15). ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! rate_control char* - Variable defining the bitrate. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! 05.12.2019 Patrick vogler B87E7E4 V 0.1.0 streamlined function arguments ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +bwc_create_compression(bwc_field *field, char *rate_control) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int8 l; + size_t size; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + float buf_f; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char *token, *ptr; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global control structure to a temporary varia- ! + ! ble to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Allocate the array used to hold the quality layer bit- ! + ! rates with an initial size of 10. ! + \*--------------------------------------------------------*/ + size = 10; + control->bitrate = calloc(size, sizeof(float)); + if(!control->bitrate) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Read the two additional arguments defining the rate con- ! + ! trol and accuracy parameters. ! + \*--------------------------------------------------------*/ + if(rate_control == NULL) + { + control->bitrate[0] = PREC_BIT + 1; + control->nLayers = 1; + } + else + { + token = strtok_r(rate_control, "-, ", &ptr); + + if(token) + { + for(control->nLayers = 0; token; token = strtok_r(NULL, "-, ", &ptr)) + { + buf_f = strtof(token, NULL); + + if(buf_f <= 0 || buf_f > 64) + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Invalid bitrate value: %-25f|\n"\ + "| |\n"\ + "| The specified bitrate is not within its valid |\n"\ + "| range of: |\n"\ + "| |\n"\ + "| 0 < Bitrate ≤ 64 |\n"\ + "| |\n"\ + "o##########################################################o\n", buf_f); + return 1; + } + + if(((int8)size - control->nLayers) == 0) + { + size += 10; + control->bitrate = realloc(control->bitrate, size * sizeof(float)); + } + + for(l = control->nLayers; l >= 0; --l) + { + if(l && buf_f < control->bitrate[l - 1]) + { + control->bitrate[l] = control->bitrate[l - 1]; + } + else if (l && fabs(buf_f - control->bitrate[l - 1]) < 0.01f) + { + for(; l < control->nLayers; ++l) + { + control->bitrate[l] = control->bitrate[l + 1]; + } + break; + } + else + { + control->bitrate[l] = buf_f; + control->nLayers++; + break; + } + } + } + } + else + { + control->bitrate[0] = PREC_BIT + 1; + control->nLayers = 1; + } + } + + control->bitrate = realloc(control->bitrate, control->nLayers * sizeof(float)); + + /*--------------------------------------------------------*\ + ! Create the field structure used to compress a floating ! + ! point array defined by the bwc_initialize function. ! + \*--------------------------------------------------------*/ + if(create_field(field)) + { + return 1; + } + + /*--------------------------------------------------------*\ + ! Create the main header for the compressed codestream and ! + ! save the memory handle in the field structure. ! + \*--------------------------------------------------------*/ + if(assemble_main_header(field)) + { + return 1; + } + + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar bwc_compress(bwc_field *const field, bwc_float *const data) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! Description needed. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +bwc_compress(bwc_field *const field, bwc_data *const data) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 buff_size = 0; + uint64 i; + uint16 p; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + double start, end; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + bwc_tile *tile; + bwc_parameter *parameter; + bwc_sample *working_buffer; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(data); + + /*--------------------------------------------------------*\ + ! Initialize the compression time measurement. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + field->meter.time.ttl = omp_get_wtime(); + #else + field->meter.time.ttl = (double)clock(); + #endif + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = field->info; + + /*--------------------------------------------------------*\ + ! Check if any auxiliary information has been supplied by ! + ! the function caller and append the header accordingly. ! + \*--------------------------------------------------------*/ + if(data->codestream.aux && header_append_aux(field, data->codestream.aux)) + { + return 1; + } + + /*--------------------------------------------------------*\ + ! Check if any commentary information has been supplied by ! + ! the function caller and append the header accordingly. ! + \*--------------------------------------------------------*/ + if(data->codestream.com && header_append_com(field, data->codestream.com)) + { + return 1; + } + + /*--------------------------------------------------------*\ + ! Set the number of Open MP threads for the current run. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + omp_set_num_threads(control->nThreads); + #endif + + /*--------------------------------------------------------*\ + ! Evaluate the working buffer size and allocate it accord- ! + ! ingly. ! + \*--------------------------------------------------------*/ + buff_size = control->tileSizeX * control->tileSizeY * + control->tileSizeZ * control->tileSizeTS; + + working_buffer = calloc(buff_size, sizeof(bwc_sample)); + if(!working_buffer) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Walk through the tile structure and compress the speci- ! + ! fied data set. ! + \*--------------------------------------------------------*/ + for(i = 0; i < control->nTiles; ++i) + { + /*--------------------------------------------------------*\ + ! Save the tile structure in a temporary variable to make ! + ! the code more readable. ! + \*--------------------------------------------------------*/ + tile = &field->tile[i]; + + for(p = 0; p < info->nPar; ++p) + { + /*--------------------------------------------------------*\ + ! Save the parameter structure in a temporary variable to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + parameter = &tile->parameter[p]; + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the flow field data for the ! + ! current tile parameter. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + start = omp_get_wtime(); + #else + start = (double)clock(); + #endif + fill_buffer(field, tile, parameter, working_buffer, data, p); + #if defined (_OPENMP) + end = omp_get_wtime(); + field->meter.time.cpy += end - start; + #else + end = (double)clock(); + field->meter.time.cpy += (end - start)/CLOCKS_PER_SEC; + #endif + + /*--------------------------------------------------------*\ + ! Normalize the working buffer to a range of [-1,1) and ! + ! scale it to the dynamic range specified by the Qm param- ! + ! eter. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + start = omp_get_wtime(); + #else + start = (double)clock(); + #endif + normalize_param(field, parameter); + #if defined (_OPENMP) + end = omp_get_wtime(); + field->meter.time.nrm += end - start; + #else + end = (double)clock(); + field->meter.time.nrm += (end - start)/CLOCKS_PER_SEC; + #endif + + /*--------------------------------------------------------*\ + ! Perform the forward discrete wavelet transform. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + start = omp_get_wtime(); + #else + start = (double)clock(); + #endif + if(forward_discrete_wavelet_transform(field, parameter)) + { + free(working_buffer); + return 1; + } + #if defined (_OPENMP) + end = omp_get_wtime(); + field->meter.time.wav += end - start; + #else + end = (double)clock(); + field->meter.time.wav += (end - start)/CLOCKS_PER_SEC; + #endif + + /*--------------------------------------------------------*\ + ! Tier1 encode the current tile parameter. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + start = omp_get_wtime(); + #else + start = (double)clock(); + #endif + if(t1_encode(field, tile, parameter)) + { + free(working_buffer); + return 1; + } + #if defined (_OPENMP) + end = omp_get_wtime(); + field->meter.time.ent += end - start; + #else + end = (double)clock(); + field->meter.time.ent += (end - start)/CLOCKS_PER_SEC; + #endif + + /*--------------------------------------------------------*\ + ! Reset the working buffer memory block. ! + \*--------------------------------------------------------*/ + memset(working_buffer, 0, buff_size * sizeof(bwc_sample)); + parameter->data = NULL; + } + /*--------------------------------------------------------*\ + ! Tier2 encode the current tile. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + start = omp_get_wtime(); + #else + start = (double)clock(); + #endif + if(t2_encode(field, tile)) + { + free(working_buffer); + return 1; + } + #if defined (_OPENMP) + end = omp_get_wtime(); + field->meter.time.ent += end - start; + #else + end = (double)clock(); + field->meter.time.ent += (end - start)/CLOCKS_PER_SEC; + #endif + } + /*--------------------------------------------------------*\ + ! Assemble compressed codestream. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + start = omp_get_wtime(); + #else + start = (double)clock(); + #endif + data->codestream.data = assemble_codestream(field); + if(!data->codestream.data) + { + free(working_buffer); + return 1; + } + #if defined (_OPENMP) + end = omp_get_wtime(); + field->meter.time.ass += end - start; + #else + end = (double)clock(); + field->meter.time.ass += (end - start)/CLOCKS_PER_SEC; + #endif + + /*--------------------------------------------------------*\ + ! Free the working buffer. ! + \*--------------------------------------------------------*/ + free(working_buffer); + + /*--------------------------------------------------------*\ + ! Calculate the compression time. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + field->meter.time.ttl = omp_get_wtime() - field->meter.time.ttl; + #else + field->meter.time.ttl = ((double)clock() - field->meter.time.ttl)/CLOCKS_PER_SEC; + #endif + + /*--------------------------------------------------------*\ + ! Return to the function caller. ! + \*--------------------------------------------------------*/ + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar bwc_create_compression(bwc_field *field_ptr, char *rate_control, uchar instr) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function parses the supplied bwc codestream and sets up the field structure used to ! +! decompress the numerical dataset. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! rate_control (opt) char* - Variable defining the bitrate/accuracy. ! +! ! +! instr (opt) bwc_rate_instr - Constants used to instruct the rate ! +! control information. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +bwc_field * +bwc_create_decompression(bwc_data *const data, uint8 layer) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_field *field; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(data); + + /*--------------------------------------------------------*\ + ! Parse the codestream and setup the field codestream. ! + \*--------------------------------------------------------*/ + field = parse_codestream(data, layer); + if(!field) + { + return NULL; + } + + /*--------------------------------------------------------*\ + ! If successful, return the field structure to the func- ! + ! tion caller. ! + \*--------------------------------------------------------*/ + return field; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar bwc_create_compression(bwc_field *field, float rate_control, uchar instr) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function creates the field structure used to compress a floating point array defined ! +! by the bwc_initialize function at a prescribed bitrate or accuracy. In this context, the ! +! bitrate is a floating point value defining the average number of bits per datapoint and ! +! the accuracy is an integer value defining the exponent of the maximum allowable error ! +! (i.e. 15 for err = 1e-15). ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! rate_control float - Variable defining the bitrate/accuracy. ! +! ! +! instr unsigned char - Constants used to instruct the rate ! +! control information. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +bwc_decompress(bwc_field *const field, bwc_data *const data) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 buff_size; + uint64 single_size, double_size; + uint64 i; + uint16 p; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + double start, end; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + bwc_tile *tile; + bwc_parameter *parameter; + bwc_sample *working_buffer; + bwc_cmd_opts_ll *param; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(data); + + /*--------------------------------------------------------*\ + ! Initialize the decompression time measurement. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + field->meter.time.ttl = omp_get_wtime(); + #else + field->meter.time.ttl = (double)clock(); + #endif + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = field->info; + + /*--------------------------------------------------------*\ + ! Set the number of Open MP threads for the current run. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + omp_set_num_threads(control->nThreads); + #endif + + /*--------------------------------------------------------*\ + ! Calculate the field size after subsampling and allocate ! + ! the field memory blocks. ! + \*--------------------------------------------------------*/ + if(data->info.parameter) + { + param = data->info.parameter->root; + double_size = + single_size = 0; + + while(param != NULL) + { + if(param->precision == 8) + { + double_size += param->size; + } + else if (param->precision == 4) + { + single_size += param->size; + } + + param = param -> next; + } + } + + data->field.d = calloc(double_size, sizeof(double)); + data->field.f = calloc(single_size, sizeof(float)); + if(!data->field.d || !data->field.f) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Evaluate the working buffer size and allocate it accord- ! + ! ingly. ! + \*--------------------------------------------------------*/ + buff_size = control->tileSizeX * control->tileSizeY * + control->tileSizeZ * control->tileSizeTS; + + working_buffer = calloc(buff_size, sizeof(bwc_sample)); + if(!working_buffer) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Walk through the tile structure and decompress the speci-! + ! fied data set. ! + \*--------------------------------------------------------*/ + for(i = 0; i < control->nTiles; ++i) + { + /*--------------------------------------------------------*\ + ! Save the tile structure in a temporary variable to make ! + ! the code more readable. ! + \*--------------------------------------------------------*/ + tile = &field->tile[i]; + + for(p = 0; p < info->nPar; ++p) + { + /*--------------------------------------------------------*\ + ! Save the parameter structure in a temporary variable to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + parameter = &tile->parameter[p]; + + /*--------------------------------------------------------*\ + ! Associate the working buffer with the data pointer in ! + ! the bwc_parameter structure. ! + \*--------------------------------------------------------*/ + parameter->data = working_buffer; + + /*--------------------------------------------------------*\ + ! Tier1 decode the current tile parameter. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + start = omp_get_wtime(); + #else + start = (double)clock(); + #endif + if(t1_decode(field, tile, parameter)) + { + free(working_buffer); + return 1; + } + #if defined (_OPENMP) + end = omp_get_wtime(); + field->meter.time.ent += end - start; + #else + end = (double)clock(); + field->meter.time.ent += (end - start)/CLOCKS_PER_SEC; + #endif + + /*--------------------------------------------------------*\ + ! Perform the inverse discrete wavelet transform. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + start = omp_get_wtime(); + #else + start = (double)clock(); + #endif + if(inverse_discrete_wavelet_transform(field, parameter)) + { + free(working_buffer); + return 1; + } + #if defined (_OPENMP) + end = omp_get_wtime(); + field->meter.time.wav += end - start; + #else + end = (double)clock(); + field->meter.time.wav += (end - start)/CLOCKS_PER_SEC; + #endif + + /*--------------------------------------------------------*\ + ! Denormalize the working buffer scale it to the original ! + ! dynamic range specified by the Qm parameter. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + start = omp_get_wtime(); + #else + start = (double)clock(); + #endif + denormalize_param(field, parameter); + #if defined (_OPENMP) + end = omp_get_wtime(); + field->meter.time.nrm += end - start; + #else + end = (double)clock(); + field->meter.time.nrm += (end - start)/CLOCKS_PER_SEC; + #endif + + /*--------------------------------------------------------*\ + ! Flush the working buffer to the appropriate memory block ! + ! in the flow field data structure for the current tile pa-! + ! rameter. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + start = omp_get_wtime(); + #else + start = (double)clock(); + #endif + flush_buffer(field, tile, parameter, working_buffer, data, p); + #if defined (_OPENMP) + end = omp_get_wtime(); + field->meter.time.cpy += end - start; + #else + end = (double)clock(); + field->meter.time.cpy += (end - start)/CLOCKS_PER_SEC; + #endif + + /*--------------------------------------------------------*\ + ! Reset the working buffer memory block. ! + \*--------------------------------------------------------*/ + memset(working_buffer, 0, buff_size * sizeof(bwc_sample)); + parameter->data = NULL; + } + } + + /*--------------------------------------------------------*\ + ! Free the working buffer. ! + \*--------------------------------------------------------*/ + free(working_buffer); + + /*--------------------------------------------------------*\ + ! Calculate the decompression time. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + field->meter.time.ttl = omp_get_wtime() - field->meter.time.ttl; + #else + field->meter.time.ttl = ((double)clock() - field->meter.time.ttl)/CLOCKS_PER_SEC; + #endif + + return 0; +} \ No newline at end of file diff --git a/src/library/mq.c b/src/library/mq.c new file mode 100755 index 0000000..41e1e1c --- /dev/null +++ b/src/library/mq.c @@ -0,0 +1,1196 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| FILE NAME: mq.c || +|| || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| FILE REFERENCES: || +|| ---------------- || +|| || +|| Name I/O Description || +|| ---- --- ----------- || +|| none - - || +|| || +|| || +|| PRIVATE FUNCTIONS: || +|| ------------------ || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 13.02.2019 Patrick Vogler B87D120 V 0.1.0 source file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ + +/************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\************************************************************************************************************/ +#include +#include +#include +#include + +#include "macros.h" +#include "mq.h" +#include "types.h" + +/************************************************************************************************************\ +|| _ _ ____ ____ ____ ____ ____ || +|| |\/| |__| | |__/ | | [__ || +|| | | | | |___ | \ |__| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! Macros: ! +! ------- ! +! Macro Description ! +! ----- ----------- ! +! ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 22.02.2019 Patrick Vogler B87D120 V 0.1.0 Macros created ! +\*----------------------------------------------------------------------------------------------------------*/ +#define transfer_byte(state) \ +{ \ + if(state->T == 0xFF) \ + { \ + if(state->L >= 0) \ + { \ + state->b[state->L] = state->T; \ + } \ + \ + state->L++; \ + state->T = (uchar)(state->C >> 0x14); \ + state->C &= 0xFFFFF; \ + state->t = 0x07; \ + } \ + else \ + { \ + if(state->C & 0x8000000) \ + { \ + state->T++; \ + state->C &= 0x7FFFFFF; \ + } \ + \ + if(state->L >= 0) \ + { \ + state->b[state->L] = state->T; \ + } \ + \ + state->L++; \ + \ + if(state->T == 0xFF) \ + { \ + state->T = (uchar)(state->C >> 0x14); \ + state->C &= 0xFFFFF; \ + state->t = 0x07; \ + } \ + else \ + { \ + state->T = (uchar)(state->C >> 0x13); \ + state->C &= 0x7FFFF; \ + state->t = 0x08; \ + } \ + } \ +} + +/*----------------------------------------------------------------------------------------------------------*\ +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! Macros: ! +! ------- ! +! Macro Description ! +! ----- ----------- ! +! ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 22.02.2019 Patrick Vogler B87D120 V 0.1.0 Macros created ! +\*----------------------------------------------------------------------------------------------------------*/ +#define fill_lsb(state, bitcoder) \ +{ \ + if((state->L == bitcoder->Lmax) || \ + ((state->T == 0xFF) && \ + (state->b[state->L] > 0x8f) )) \ + { \ + state->t = 8; \ + state->C += 0xFF; \ + } \ + else \ + { \ + if((state->T == 0xFF)) \ + { \ + state->t = 7; \ + state->T = state->b[state->L]; \ + state->C += (uint32)state->T << 1; \ + state->L++; \ + } \ + else \ + { \ + state->t = 8; \ + state->T = state->b[state->L]; \ + state->C += (uint32)state->T; \ + state->L++; \ + } \ + } \ +} + +/************************************************************************************************************\ +|| ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || +|| | | | |\ | [__ | |__| |\ | | [__ || +|| |___ |__| | \| ___] | | | | \| | ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! DESCRIPTION: ! +! ------------ ! +! These constants define the probability state transition table as described in JPEG2000 by ! +! David S. Taubman and Michael W. Marcellin (p. 75). In order to avoid the the Most Probable ! +! Symbol and Least Probable Symbol exchange during encoding, the table has been expanded to ! +! store the Most Probable Symbol sk instead of the function Xs. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static const bwc_context_state context_state[94] = +{{0x5601, 0, &context_state[ 1], &context_state[48]}, + {0x3401, 0, &context_state[ 2], &context_state[ 6]}, + {0x1801, 0, &context_state[ 3], &context_state[ 9]}, + {0x0AC1, 0, &context_state[ 4], &context_state[12]}, + {0x0521, 0, &context_state[ 5], &context_state[29]}, + {0x0221, 0, &context_state[38], &context_state[33]}, + {0x5601, 0, &context_state[ 7], &context_state[53]}, + {0x5401, 0, &context_state[ 8], &context_state[14]}, + {0x4801, 0, &context_state[ 9], &context_state[14]}, + {0x3801, 0, &context_state[10], &context_state[14]}, + {0x3001, 0, &context_state[11], &context_state[17]}, + {0x2401, 0, &context_state[12], &context_state[18]}, + {0x1C01, 0, &context_state[13], &context_state[20]}, + {0x1601, 0, &context_state[29], &context_state[21]}, + {0x5601, 0, &context_state[15], &context_state[61]}, + {0x5401, 0, &context_state[16], &context_state[14]}, + {0x5101, 0, &context_state[17], &context_state[15]}, + {0x4801, 0, &context_state[18], &context_state[16]}, + {0x3801, 0, &context_state[19], &context_state[17]}, + {0x3401, 0, &context_state[20], &context_state[18]}, + {0x3001, 0, &context_state[21], &context_state[19]}, + {0x2801, 0, &context_state[22], &context_state[19]}, + {0x2401, 0, &context_state[23], &context_state[20]}, + {0x2201, 0, &context_state[24], &context_state[21]}, + {0x1C01, 0, &context_state[25], &context_state[22]}, + {0x1801, 0, &context_state[26], &context_state[23]}, + {0x1601, 0, &context_state[27], &context_state[24]}, + {0x1401, 0, &context_state[28], &context_state[25]}, + {0x1201, 0, &context_state[29], &context_state[26]}, + {0x1101, 0, &context_state[30], &context_state[27]}, + {0x0AC1, 0, &context_state[31], &context_state[28]}, + {0x09C1, 0, &context_state[32], &context_state[29]}, + {0x08A1, 0, &context_state[33], &context_state[30]}, + {0x0521, 0, &context_state[34], &context_state[31]}, + {0x0441, 0, &context_state[35], &context_state[32]}, + {0x02A1, 0, &context_state[36], &context_state[33]}, + {0x0221, 0, &context_state[37], &context_state[34]}, + {0x0141, 0, &context_state[38], &context_state[35]}, + {0x0111, 0, &context_state[39], &context_state[36]}, + {0x0085, 0, &context_state[40], &context_state[37]}, + {0x0049, 0, &context_state[41], &context_state[38]}, + {0x0025, 0, &context_state[42], &context_state[39]}, + {0x0015, 0, &context_state[43], &context_state[40]}, + {0x0009, 0, &context_state[44], &context_state[41]}, + {0x0005, 0, &context_state[45], &context_state[42]}, + {0x0001, 0, &context_state[45], &context_state[43]}, + {0x5601, 0, &context_state[46], &context_state[46]}, + {0x5601, 1, &context_state[48], &context_state[ 1]}, + {0x3401, 1, &context_state[49], &context_state[53]}, + {0x1801, 1, &context_state[50], &context_state[56]}, + {0x0AC1, 1, &context_state[51], &context_state[59]}, + {0x0521, 1, &context_state[52], &context_state[76]}, + {0x0221, 1, &context_state[85], &context_state[80]}, + {0x5601, 1, &context_state[54], &context_state[ 6]}, + {0x5401, 1, &context_state[55], &context_state[61]}, + {0x4801, 1, &context_state[56], &context_state[61]}, + {0x3801, 1, &context_state[57], &context_state[61]}, + {0x3001, 1, &context_state[58], &context_state[64]}, + {0x2401, 1, &context_state[59], &context_state[65]}, + {0x1C01, 1, &context_state[60], &context_state[67]}, + {0x1601, 1, &context_state[76], &context_state[68]}, + {0x5601, 1, &context_state[62], &context_state[14]}, + {0x5401, 1, &context_state[63], &context_state[61]}, + {0x5101, 1, &context_state[64], &context_state[62]}, + {0x4801, 1, &context_state[65], &context_state[63]}, + {0x3801, 1, &context_state[66], &context_state[64]}, + {0x3401, 1, &context_state[67], &context_state[65]}, + {0x3001, 1, &context_state[68], &context_state[66]}, + {0x2801, 1, &context_state[69], &context_state[66]}, + {0x2401, 1, &context_state[70], &context_state[67]}, + {0x2201, 1, &context_state[71], &context_state[68]}, + {0x1C01, 1, &context_state[72], &context_state[69]}, + {0x1801, 1, &context_state[73], &context_state[70]}, + {0x1601, 1, &context_state[74], &context_state[71]}, + {0x1401, 1, &context_state[75], &context_state[72]}, + {0x1201, 1, &context_state[76], &context_state[73]}, + {0x1101, 1, &context_state[77], &context_state[74]}, + {0x0AC1, 1, &context_state[78], &context_state[75]}, + {0x09C1, 1, &context_state[79], &context_state[76]}, + {0x08A1, 1, &context_state[80], &context_state[77]}, + {0x0521, 1, &context_state[81], &context_state[78]}, + {0x0441, 1, &context_state[82], &context_state[79]}, + {0x02A1, 1, &context_state[83], &context_state[80]}, + {0x0221, 1, &context_state[84], &context_state[81]}, + {0x0141, 1, &context_state[85], &context_state[82]}, + {0x0111, 1, &context_state[86], &context_state[83]}, + {0x0085, 1, &context_state[87], &context_state[84]}, + {0x0049, 1, &context_state[88], &context_state[85]}, + {0x0025, 1, &context_state[89], &context_state[86]}, + {0x0015, 1, &context_state[90], &context_state[87]}, + {0x0009, 1, &context_state[91], &context_state[88]}, + {0x0005, 1, &context_state[92], &context_state[89]}, + {0x0001, 1, &context_state[92], &context_state[90]}, + {0x5601, 1, &context_state[93], &context_state[93]}}; + +/************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void initialize_bit_encoder(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +initialize_bit_encoder(bwc_coder *const coder, const uint8 number_of_contexts) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint8 i; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_bit_coder *bitcoder; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + assert(coder->compressed); + + coder->bitcoder = calloc(1, sizeof(bwc_bit_coder)); + if(!coder->bitcoder) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + bitcoder = coder->bitcoder; + + bitcoder->nContext = number_of_contexts; + + bitcoder->b = coder->compressed; + + bitcoder->context = calloc(bitcoder->nContext, sizeof(bwc_context_state*)); + if(!bitcoder->context) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + for(i = 0; i < number_of_contexts; ++i) + { + bitcoder->context[i] = &context_state[0]; + } + + bitcoder->context[CONTEXT_SIG] = &context_state[ 4]; + bitcoder->context[CONTEXT_RUN] = &context_state[ 3]; + bitcoder->context[CONTEXT_UNI] = &context_state[46]; + + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void initialize_bit_encoder(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +bit_encoder_next_run(bwc_bit_coder *const bitcoder) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_state *state; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(bitcoder); + + state = calloc(1, sizeof(bwc_coder_state)); + if(!state) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + if(bitcoder->state) + { + memcpy(state, bitcoder->state, sizeof(bwc_coder_state)); + state->prev = bitcoder->state; + bitcoder->state->next = state; + bitcoder->state = state; + } + else + { + bitcoder->state = state; + bitcoder->state->b = bitcoder->b; + + state->A = 0x8000; + state->t = 0x000C; + state->L = -0x0001; + } + + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void initialize_bit_encoder(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bit_encode(bwc_bit_coder *const bitcoder, const uint8 s, const uint8 k) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint16 p; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(bitcoder); + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_context_state const **context; + bwc_coder_state *state; + + context = bitcoder->context; + state = bitcoder->state; + + p = context[k]->p; + + state->A -= p; + + if(s == context[k]->sk) + { + if(state->A >= 0x8000) + { + state->C += p; + } + else + { + if(state->A < p) + { + state->A = p; + } + else + { + state->C += p; + } + context[k] = context[k]->MPS; + + do + { + state->A <<= 1; + state->C <<= 1; + state->t --; + if(state->t == 0) + { + transfer_byte(state); + } + } while (state->A < 0x8000); + } + } + else + { + if(state->A < p) + { + state->C += p; + } + else + { + state->A = p; + } + context[k] = context[k]->LPS; + + do + { + state->A <<= 1; + state->C <<= 1; + state->t --; + if(state->t == 0) + { + transfer_byte(state); + } + } while (state->A < 0x8000); + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void initialize_bit_encoder(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bit_encoder_truncation_length_min(bwc_coder_state *const state) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + #ifdef BWC_SINGLE_PRECISION + int32 buff, CrDec, CrFrac; + int32 CArDec, CArFrac; + uint8 s; + #else + int64 buff, Cr, CAr; + int8 s; + #endif + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(state); + + #ifdef BWC_SINGLE_PRECISION + CrFrac = (int32)state->C << state->t; + CArFrac = ((int32)state->A << state->t) + CrFrac; + + CrDec = state->T; + CArDec = state->T; + + CrDec += 0x01 & (CrFrac >> 27); + CArDec += 0x01 & (CArFrac >> 27); + + CrFrac &= 0x7FFFFFF; + CArFrac &= 0x7FFFFFF; + + s = 8; + + while((CrDec > 0xff) || + (CArDec <= 0xff)) + { + buff = (state->L >= 0) ? (int32)state->b[state->L] : 0; + state->L++; + + CrDec -= buff << (8 - s); + CArDec -= buff << (8 - s); + + CrDec <<= s; + CArDec <<= s; + + CrDec += CrFrac >> (27 - s); + CArDec += CArFrac >> (27 - s); + + CrFrac <<= s; + CArFrac <<= s; + + CrFrac &= 0x7FFFFFF; + CArFrac &= 0x7FFFFFF; + + s = (buff == 0xFF) ? 7 : 8; + } + #else + Cr = ((int64)state->T << 27) + + ((int64)state->C << state->t); + CAr = ((int64)state->A << state->t) + Cr; + s = 8; + + while(((Cr >> 27) > 0xff) || + ((CAr >> 27) <= 0xff)) + { + buff = (state->L >= 0) ? (int64)state->b[state->L] : 0; + state->L++; + + Cr -= buff << (35 - s); + CAr -= buff << (35 - s); + + Cr <<= s; + CAr <<= s; + + s = (buff == 0xFF) ? 7 : 8; + } + #endif + + if(state->L > 0 && (state->b[state->L - 1] == 0xFF)) + { + state->L--; + } + while(state->L > 1 && (state->b[state->L - 2] == 0xFF) && + (state->b[state->L - 1] == 0x7F)) + { + state->L -= 2; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void initialize_bit_encoder(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bit_encoder_termination(bwc_bit_coder *const bitcoder) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int8 n; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_state buff; + bwc_coder_state *state; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(bitcoder); + + state = bitcoder->state; + + buff.A = state->A; + buff.C = state->C; + buff.L = state->L; + buff.T = state->T; + buff.t = state->t; + + n = 12 - state->t; + state->C <<= state->t; + + while(n > 0) + { + transfer_byte(state); + n -= state->t; + state->C <<= state->t; + } + transfer_byte(state); + + state->A = buff.A; + state->C = buff.C; + state->L = buff.L; + state->T = buff.T; + state->t = buff.t; + + while(state->prev) + { + state = state->prev; + } + + while(state) + { + bit_encoder_truncation_length_min(state); + state = state->next; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void initialize_bit_encoder(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +free_bit_encoder(bwc_coder *const coder) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + + if(coder->bitcoder) + { + while(coder->bitcoder->state->next) + { + coder->bitcoder->state = coder->bitcoder->state->next; + } + + while(coder->bitcoder->state->prev) + { + coder->bitcoder->state = coder->bitcoder->state->prev; + free(coder->bitcoder->state->next); + } + + free(coder->bitcoder->state); + free(coder->bitcoder->context); + } + + free(coder->bitcoder); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void initialize_bit_encoder(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +initialize_bit_decoder(bwc_coder *const coder, const uint8 number_of_contexts, const int64 Lmax) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint8 i; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_bit_coder *bitcoder; + bwc_coder_state *state; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + assert(coder->compressed); + + coder->bitcoder = calloc(1, sizeof(bwc_bit_coder)); + if(!coder->bitcoder) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + bitcoder = coder->bitcoder; + + bitcoder->Lmax = Lmax; + bitcoder->nContext = number_of_contexts; + + bitcoder->b = coder->compressed; + + bitcoder->context = calloc(bitcoder->nContext, sizeof(bwc_context_state*)); + if(!bitcoder->context) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + for(i = 0; i < number_of_contexts; ++i) + { + bitcoder->context[i] = &context_state[0]; + } + + bitcoder->context[CONTEXT_SIG] = &context_state[ 4]; + bitcoder->context[CONTEXT_RUN] = &context_state[ 3]; + bitcoder->context[CONTEXT_UNI] = &context_state[46]; + + bitcoder->state = calloc(1, sizeof(bwc_coder_state)); + if(!bitcoder->state) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + state = bitcoder->state; + state->b = coder->compressed; + + fill_lsb(state, bitcoder); + + state->C <<= 0x08; + + fill_lsb(state, bitcoder); + + state->C <<= 0x07; + state->t -= 0x07; + state->A = 0x8000; + + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void initialize_bit_encoder(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uint8 +bit_decode(bwc_bit_coder *const bitcoder, const uint8 k) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint16 p; + uint8 x; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(bitcoder); + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_context_state const **context; + bwc_coder_state *state; + + context = bitcoder->context; + state = bitcoder->state; + + p = context[k]->p; + x = context[k]->sk; + + state->A -= p; + + if((state->C >> 8) >= p) + { + state->C -= p << 8; + state->C &= 0xFFFFFF; + if(~state->A & 0x8000) + { + if(state->A < p) + { + x = 1 - x; + context[k] = context[k]->LPS; + } + else + { + context[k] = context[k]->MPS; + } + do + { + if(state->t == 0) + { + fill_lsb(state, bitcoder); + } + state->A <<= 1; + state->C <<= 1; + state->t -= 1; + } while (~state->A & 0x8000); + } + } + else + { + if(state->A MPS; + } + else + { + x = 1 - x; + context[k] = context[k]->LPS; + } + state->A = p; + do + { + if(state->t == 0) + { + fill_lsb(state, bitcoder); + } + state->A <<= 1; + state->C <<= 1; + state->t -= 1; + } while (~state->A & 0x8000); + } + + return x; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void initialize_bit_encoder(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uint64 +bit_coder_get_no_bytes(bwc_bit_coder *const bitcoder) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(bitcoder); + + return (uint64)(bitcoder->state->b - bitcoder->b) + bitcoder->state->L; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void initialize_bit_encoder(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bit_coder_reset_ptr(bwc_bit_coder *const bitcoder, uchar *const memory) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_state *state; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(bitcoder); + + state = bitcoder->state; + + bitcoder->b = memory; + + while(state) + { + state->b = memory; + state = state->prev; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void initialize_bit_encoder(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +bit_coder_get_pass_lengths(bwc_bit_coder *const bitcoder, bwc_encoded_cblk *const encoded_cblk) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint8 j; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_state *state; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(bitcoder); + assert(encoded_cblk); + + state = bitcoder->state; + + for(j = encoded_cblk->Z; (j --> 0) && state; state = state->prev) + { + encoded_cblk->L[j] = (uint64)(state->b - bitcoder->b) + state->L; + } +} \ No newline at end of file diff --git a/src/library/tagtree.c b/src/library/tagtree.c new file mode 100755 index 0000000..48da94c --- /dev/null +++ b/src/library/tagtree.c @@ -0,0 +1,594 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| FILE NAME: tagtree.c || +|| || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| FILE REFERENCES: || +|| ---------------- || +|| || +|| Name I/O Description || +|| ---- --- ----------- || +|| none - - || +|| || +|| || +|| PRIVATE FUNCTIONS: || +|| ------------------ || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| - kill_tagtree || +|| - reset_tagtree || +|| - tagtree_get_value || +|| - tagtree_set_value || +|| - initialize_tagtree || +|| - encode_tagtree || +|| - decode_tagtree || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 18.05.2018 Patrick Vogler B87D120 V 0.1.0 source file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ + +/************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\************************************************************************************************************/ +#include +#include +#include + +#include "bitstream.h" +#include "macros.h" +#include "types.h" +#include "tagtree.h" + +/************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void kill_tagtree(bwc_tagtree* tagtree) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function deallocates a tagtree instance used to encode codeblock contributions to a ! +! specific quality layer as well as the number of magnitude bit planes used to represent the ! +! samples of a specific codeblock. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! tagtree bwc_tagtree* - Structure defining a tagtree instance. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 14.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +kill_tagtree(bwc_tagtree* tagtree) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(tagtree); + + free(tagtree->nodes); + free(tagtree); + return; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 14.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +reset_tagtree(bwc_tagtree* const tagtree) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i = 0; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(tagtree); + + do + { + tagtree->nodes[i].value = 0xFFFF; + tagtree->nodes[i].threshold = 0; + }while(tagtree->nodes[i++].parent); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 14.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uint16 +tagtree_get_value(const bwc_tagtree* const tagtree, const uint64 leaf_index) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(tagtree); + assert(leaf_index < tagtree->leavesX * tagtree->leavesY * tagtree->leavesZ * tagtree->leavesTS); + assert(tagtree->nodes[leaf_index].value != 0xFFFF); + + return tagtree->nodes[leaf_index].value; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 14.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +tagtree_set_value(bwc_tagtree* const tagtree, const uint64 leaf_index, const uint16 value) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_tagtree_node *node; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(tagtree); + assert(leaf_index < tagtree->leavesX * tagtree->leavesY * tagtree->leavesZ * tagtree->leavesTS); + assert(tagtree->nodes[leaf_index].value == 0xFFFF); + assert(value < 0xFFFF); + + node = &tagtree->nodes[leaf_index]; + + do + { + node->value = value; + node = node->parent; + }while(node && (node->value > value)); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 14.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +bwc_tagtree* +initialize_tagtree(const uint64 leafsX, const uint64 leafsY, const uint64 leafsZ, const uint64 leafsTS) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 levels, number_of_nodes; + uint32 nlX[32] = {0}, nlY[32] = {0}, nlZ[32] = {0}, nlTS[32] = {0}; + uint32 i, j, k, l, n; + uint16 a,b,c,d; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_tagtree_node *node, *parent_x, *parent_y, *parent_z, *parent_ts; + bwc_tagtree *tagtree; + + for(nlX[0] = leafsX, nlY[0] = leafsY, + nlZ[0] = leafsZ, nlTS[0] = leafsTS, + levels = 0, number_of_nodes = 1; + nlX[levels] * nlY[levels] * + nlZ[levels] * nlTS[levels] > 1; + ++levels) + { + number_of_nodes += nlX[levels] * nlY[levels] * nlZ[levels] * nlTS[levels]; + nlX[levels + 1] = (nlX[levels] + 1) >> 1; + nlY[levels + 1] = (nlY[levels] + 1) >> 1; + nlZ[levels + 1] = (nlZ[levels] + 1) >> 1; + nlTS[levels + 1] = (nlTS[levels] + 1) >> 1; + } + + tagtree = calloc(1, sizeof(bwc_tagtree)); + if (!tagtree) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 0; + } + + tagtree->nodes = calloc(number_of_nodes, sizeof(bwc_tagtree_node)); + if (!tagtree->nodes) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(tagtree); + return 0; + } + + node = tagtree->nodes; + + for(i = 0; i < number_of_nodes; ++i) + { + node->index = i; + ++node; + } + + tagtree->leavesX = leafsX; + tagtree->leavesY = leafsY; + tagtree->leavesZ = leafsZ; + tagtree->leavesTS = leafsTS; + + parent_ts = tagtree->nodes; + node = tagtree->nodes; + for(n = 0; n < levels; ++n) + { + parent_ts += (uint32)(nlX[n] * nlY[n] * nlZ[n] * nlTS[n]); + for(l = 0, d = 0; l < nlTS[n]; ++l, ++d) + { + if(d >> 1) + { + parent_ts += nlX[n+1] * nlY[n+1] * nlZ[n+1]; + d = 0; + } + for(k = 0, c = 0, parent_z = parent_ts; k < nlZ[n]; ++k, ++c) + { + if(c >> 1) + { + parent_z += nlX[n+1] * nlY[n+1]; + c = 0; + } + for(j = 0, b = 0, parent_y = parent_z; j < nlY[n]; ++j, ++b) + { + if(b >> 1) + { + parent_y += nlY[n + 1]; + b = 0; + } + for(i = 0, a = 0, parent_x = parent_y; i < nlX[n]; ++i, ++a) + { + if(a >> 1) + { + parent_x++; + a = 0; + } + node->parent = parent_x; + node++; + } + } + } + } + } + reset_tagtree(tagtree); + return tagtree; +} + + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 14.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +void +encode_tagtree(bwc_tagtree *const tagtree, bwc_stream *const stream, const uint32 threshold, const uint32 leaf_index, const uchar estimate) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint32 threshold_tmp, threshold_min; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_tagtree_node *node; + bwc_tagtree_node **branch_ptr, *branch[32]; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(tagtree); + assert(stream); + assert(leaf_index < (tagtree->leavesX * tagtree->leavesY * tagtree->leavesZ * tagtree->leavesTS)); + + node = &tagtree->nodes[leaf_index]; + branch_ptr = branch; + + while(node->parent) + { + *branch_ptr++ = node; + node = node->parent; + } + + for(threshold_min = 0; ; node = *--branch_ptr) + { + threshold_tmp = node->threshold; + + if(threshold_tmp < threshold_min) + { + threshold_tmp = threshold_min; + } + while((node->value >= threshold_tmp) && (threshold_tmp < threshold)) //this conditional jump needs to be checked + { + threshold_tmp++; + if(node->value >= threshold_tmp) + { + bwc_emit_bit(stream, 0); + } + else + { + bwc_emit_bit(stream, 1); + } + } + + threshold_min = MIN(node->value, threshold_tmp); + + if(!estimate) + { + node->threshold = threshold_tmp; + } + + if(node == &tagtree->nodes[leaf_index]) + { + break; + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 14.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +decode_tagtree(bwc_tagtree *const tagtree, bwc_stream *const stream, const uint32 threshold, const uint32 leaf_index) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint32 threshold_min; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_tagtree_node *node; + bwc_tagtree_node **branch_ptr, *branch[32]; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(tagtree); + assert(stream); + assert(leaf_index < (tagtree->leavesX * tagtree->leavesY * tagtree->leavesZ * tagtree->leavesTS)); + + node = &tagtree->nodes[leaf_index]; + branch_ptr = branch; + + while(node) + { + if(node->value == 0xFFFF) + { + node->value = 0; + } + + *branch_ptr++ = node; + node = node->parent; + } + + for(*branch_ptr--, node = *branch_ptr--, threshold_min = 0; ; node = *branch_ptr--) + { + if(node->threshold < threshold_min) + { + node->value = threshold_min; + node->threshold = threshold_min; + } + while((node->value == node->threshold) && (node->threshold < threshold)) + { + node->threshold++; + if(!bwc_get_bit(stream)) + { + node->value++; + } + } + + threshold_min = MIN(node->value, node->threshold); + + if(node == &tagtree->nodes[leaf_index]) + { + break; + } + } + return (node->value < threshold) ? 0 : 1; +} \ No newline at end of file diff --git a/src/library/tier1.c b/src/library/tier1.c new file mode 100755 index 0000000..3c47bdb --- /dev/null +++ b/src/library/tier1.c @@ -0,0 +1,3381 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| FILE NAME: tier1.c || +|| || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| FILE REFERENCES: || +|| ---------------- || +|| || +|| Name I/O Description || +|| ---- --- ----------- || +|| none - - || +|| || +|| || +|| PRIVATE FUNCTIONS: || +|| ------------------ || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| - Patrick Vogler B87D120 V 0.1.0 source file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ + +/************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\************************************************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#include "constants.h" +#include "macros.h" +#include "types.h" +#include "dwt.h" +#include "mq.h" +#include "tier1.h" + +/************************************************************************************************************\ +|| _ _ ____ ____ ____ ____ ____ || +|| |\/| |__| | |__/ | | [__ || +|| | | | | |___ | \ |__| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! Macros: ! +! ------- ! +! Macro Description ! +! ----- ----------- ! +! ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 01.02.2019 Patrick Vogler B87D120 V 0.1.0 Macros created ! +\*----------------------------------------------------------------------------------------------------------*/ +#define encode_segmark(bitcoder) \ +{ \ + bit_encode(bitcoder, 1, CONTEXT_UNI); \ + bit_encode(bitcoder, 0, CONTEXT_UNI); \ + bit_encode(bitcoder, 1, CONTEXT_UNI); \ + bit_encode(bitcoder, 0, CONTEXT_UNI); \ +} + +/************************************************************************************************************\ +|| ____ _ _ ___ ____ ____ _ _ ____ _ ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || +|| |___ \/ | |___ |__/ |\ | |__| | | | | |\ | [__ | |__| |\ | | [__ || +|| |___ _/\_ | |___ | \ | \| | | |___ |___ |__| | \| ___] | | | | \| | ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! DESCRIPTION: ! +! ------------ ! +! These constants define the distortion estimation for the significance propagation (TS) ! +! and magnitude refinement (TM) pass as lookup tables. These lookup tables were evaluated ! +! using the appropriate equations from JPEG2000 by David S. Taubman and Michael W. Marcellin ! +! (p. 378): ! +! ! +! 𝛥D_i^(p,k) = G_bi × 𝛥_i^2 × 2^2p × ! +! ┌ ! +! | ∑_{j∈P_i^(p,k), ν_i^p = 1} TS(νtilde_i^(p+1)[j]) + ! +! └ ┐ ! +! ∑_{j∈P_i^(p,k), ν_i^p>1} TM(νtilde_i^(p+1)[j]) | ! +! ┘ ! +! TS(νtilde) = (2νtilde)^2 - (2νtilde - 1 - δ)^2 ! +! TM(νtilde) = (2νtilde - 1)^2 - (2νtilde - ⌊2νtilde^(p+1)⌋ - δ)^2 ! +! ! +! here 𝛥D_i^(p,k) describes the aggregate distortion contribution, G_bi the energy gain fac- ! +! tor for subband b_i, 𝛥_i the quantization step-size, ν_i the quantization magnitude, νtilde ! +! the fraction part of ν_i, ν_i^p the quantization magnitude obtained by dropping the last p ! +! bits of v_i and TS/TM the respective lookup tables. The index p is used to identify a spe- ! +! cific bitplane. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 23.01.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static const int32 DISTORTION_TM_LUT[64] = +{49152, 47104, 45056, 43008, + 40960, 38912, 36864, 34816, + 32768, 30720, 28672, 26624, + 24576, 22528, 20480, 18432, + 16384, 14336, 12288, 10240, + 8192, 6144, 4096, 2048, + 0, -2048, -4096, -6144, + -8192,-10240,-12288,-14336, +-16384,-14336,-12288,-10240, + -8192, -6144, -4096, -2048, + 0, 2048, 4096, 6144, + 8192, 10240, 12288, 14336, + 16384, 18432, 20480, 22528, + 24576, 26624, 28672, 30720, + 32768, 34816, 36864, 38912, + 40960, 43008, 45056, 47104}; + +static const int32 DISTORTION_TS_LUT[32] = +{49152, 55296, 61440, 67584, + 73728, 79872, 86016, 92160, + 98304, 104448, 110592, 116736, +122880, 129024, 135168, 141312, +147456, 153600, 159744, 165888, +172032, 178176, 184320, 190464, +196608, 202752, 208896, 215040, +221184, 227328, 233472, 239616}; + +/*----------------------------------------------------------------------------------------------------------*\ +! DESCRIPTION: ! +! ------------ ! +! These constants define a lookup table that is used to calculate the number of leading zeros ! +! in a pseudo 4-bit integer variable. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 15.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static const int32 DISTORTION_LZ_LUT[15] = +{0, 3, 0, 2, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0}; + + +/*----------------------------------------------------------------------------------------------------------*\ +! DESCRIPTION: ! +! ------------ ! +! - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 08.03.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static const uint16 frac2log[256] = +{ 0, 1, 2, 4, 5, 7, 8, 9, 11, 12, 14, 15, 16, 18, 19, 21, + 22, 23, 25, 26, 27, 29, 30, 31, 33, 34, 35, 37, 38, 39, 40, 42, + 43, 44, 46, 47, 48, 49, 51, 52, 53, 54, 56, 57, 58, 59, 61, 62, + 63, 64, 65, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 80, 81, + 82, 83, 84, 85, 87, 88, 89, 90, 91, 92, 93, 94, 96, 97, 98, 99, +100, 101, 102, 103, 104, 105, 106, 108, 109, 110, 111, 112, 113, 114, 115, 116, +117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 131, 132, 133, +134, 135, 136, 137, 138, 139, 140, 140, 141, 142, 143, 144, 145, 146, 147, 148, +149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 162, 163, +164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 173, 174, 175, 176, 177, 178, +179, 180, 181, 181, 182, 183, 184, 185, 186, 187, 188, 188, 189, 190, 191, 192, +193, 194, 194, 195, 196, 197, 198, 199, 200, 200, 201, 202, 203, 204, 205, 205, +206, 207, 208, 209, 209, 210, 211, 212, 213, 214, 214, 215, 216, 217, 218, 218, +219, 220, 221, 222, 222, 223, 224, 225, 225, 226, 227, 228, 229, 229, 230, 231, +232, 232, 233, 234, 235, 235, 236, 237, 238, 239, 239, 240, 241, 242, 242, 243, +244, 245, 245, 246, 247, 247, 248, 249, 250, 250, 251, 252, 253, 253, 254, 255}; + +/*----------------------------------------------------------------------------------------------------------*\ +! DESCRIPTION: ! +! ------------ ! +! - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 08.03.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static const uint8 SIG2CONTEXT_L[45] = +{CONTEXT_SIG + 0, CONTEXT_SIG + 1, CONTEXT_SIG + 2, CONTEXT_SIG + 2, CONTEXT_SIG + 2, + CONTEXT_SIG + 3, CONTEXT_SIG + 3, CONTEXT_SIG + 3, CONTEXT_SIG + 3, CONTEXT_SIG + 3, + CONTEXT_SIG + 4, CONTEXT_SIG + 4, CONTEXT_SIG + 4, CONTEXT_SIG + 4, CONTEXT_SIG + 4, + CONTEXT_SIG + 5, CONTEXT_SIG + 6, CONTEXT_SIG + 6, CONTEXT_SIG + 6, CONTEXT_SIG + 6, + CONTEXT_SIG + 7, CONTEXT_SIG + 7, CONTEXT_SIG + 7, CONTEXT_SIG + 7, CONTEXT_SIG + 7, + CONTEXT_SIG + 7, CONTEXT_SIG + 7, CONTEXT_SIG + 7, CONTEXT_SIG + 7, CONTEXT_SIG + 7, + CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, + CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, + CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8}; + +static const uint8 SIG2CONTEXT_H[45] = +{CONTEXT_SIG + 0, CONTEXT_SIG + 1, CONTEXT_SIG + 2, CONTEXT_SIG + 2, CONTEXT_SIG + 2, + CONTEXT_SIG + 5, CONTEXT_SIG + 6, CONTEXT_SIG + 6, CONTEXT_SIG + 6, CONTEXT_SIG + 6, + CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, + CONTEXT_SIG + 3, CONTEXT_SIG + 3, CONTEXT_SIG + 3, CONTEXT_SIG + 3, CONTEXT_SIG + 3, + CONTEXT_SIG + 7, CONTEXT_SIG + 7, CONTEXT_SIG + 7, CONTEXT_SIG + 7, CONTEXT_SIG + 7, + CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, + CONTEXT_SIG + 4, CONTEXT_SIG + 4, CONTEXT_SIG + 4, CONTEXT_SIG + 4, CONTEXT_SIG + 4, + CONTEXT_SIG + 7, CONTEXT_SIG + 7, CONTEXT_SIG + 7, CONTEXT_SIG + 7, CONTEXT_SIG + 7, + CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8, CONTEXT_SIG + 8}; + +static const uint8 SIG2CONTEXT_HH[45] = +{CONTEXT_SIG + 0, CONTEXT_SIG + 3, CONTEXT_SIG + 6, CONTEXT_SIG + 8, CONTEXT_SIG + 8, + CONTEXT_SIG + 1, CONTEXT_SIG + 4, CONTEXT_SIG + 7, CONTEXT_SIG + 8, CONTEXT_SIG + 8, + CONTEXT_SIG + 2, CONTEXT_SIG + 5, CONTEXT_SIG + 7, CONTEXT_SIG + 8, CONTEXT_SIG + 8, + CONTEXT_SIG + 1, CONTEXT_SIG + 4, CONTEXT_SIG + 7, CONTEXT_SIG + 8, CONTEXT_SIG + 8, + CONTEXT_SIG + 2, CONTEXT_SIG + 5, CONTEXT_SIG + 7, CONTEXT_SIG + 8, CONTEXT_SIG + 8, + CONTEXT_SIG + 2, CONTEXT_SIG + 5, CONTEXT_SIG + 7, CONTEXT_SIG + 8, CONTEXT_SIG + 8, + CONTEXT_SIG + 2, CONTEXT_SIG + 5, CONTEXT_SIG + 7, CONTEXT_SIG + 8, CONTEXT_SIG + 8, + CONTEXT_SIG + 2, CONTEXT_SIG + 5, CONTEXT_SIG + 7, CONTEXT_SIG + 8, CONTEXT_SIG + 8, + CONTEXT_SIG + 2, CONTEXT_SIG + 5, CONTEXT_SIG + 7, CONTEXT_SIG + 8, CONTEXT_SIG + 8}; + +static const uint8_t SIG2XI[16] = +{1, 2, 2, 2, + 1, 0, 2, 1, + 1, 2, 0, 1, + 1, 0, 0, 0}; + +static const uint8_t XI2CONT[11][2] = +{{CONTEXT_SIGN + 4, 1}, {CONTEXT_SIGN + 3, 1}, {CONTEXT_SIGN + 2, 1}, + {0, 0}, + {CONTEXT_SIGN + 1, 1}, {CONTEXT_SIGN , 0}, {CONTEXT_SIGN + 1, 0}, + {0, 0}, + {CONTEXT_SIGN + 2, 0}, {CONTEXT_SIGN + 3, 0}, {CONTEXT_SIGN + 4, 0}}; + +/************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void cblkreset_fwd(bwc_coder_stripe *const cblk, uint64 cblksize) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to reset the codeblock memory block used to store the quantized ! +! wavelet samples alongside their sample states. This function should be called after ! +! encoding a codeblock. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! cblk bwc_coder_stripe* - Pointer to the codeblock memory block. ! +! cblksize unsigned int(64 bit) - Size of the codeblock. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 10.12.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +cblkreset_fwd(bwc_coder_stripe *const cblk, uint64 cblksize) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe buff; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(cblk); + + /*--------------------------------------------------------*\ + ! Walk through the cblk memory block. ! + \*--------------------------------------------------------*/ + for(i = 0; i < cblksize; ++i) + { + /*--------------------------------------------------------*\ + ! Save the sample bit and context memory address in a tem- ! + ! porary variables. ! + \*--------------------------------------------------------*/ + buff.sample = cblk[i].sample; + buff.bit = cblk[i].bit; + + /*--------------------------------------------------------*\ + ! Reset the bwc_coder_stripe structure and the memory block! + ! used to hold the sample bits of the wavelet coefficients.! + \*--------------------------------------------------------*/ + memset(&cblk[i], 0, sizeof(bwc_coder_stripe)); + memset(buff.bit, 0, PREC_BIT * sizeof(uint8)); + memset(buff.sample, 0, 4 * sizeof(uint64)); + + /*--------------------------------------------------------*\ + ! Store the memory address of the sample, bit and context ! + ! variables in the bwc_coder_stripe structure. ! + \*--------------------------------------------------------*/ + cblk[i].sample = buff.sample; + cblk[i].bit = buff.bit; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void cblkreset_inv(bwc_coder_stripe *const cblk, const uint64 width, const uint64 height, ! +! const uint64 depth, const uint64 dt) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to reset the codeblock memory block used to store the quantized ! +! wavelet samples alongside their sample states. This function should be called before ! +! decoding a codeblock. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! cblk bwc_coder_stripe* - Pointer to the codeblock memory block. ! +! width, height, depth, dt unsigned int(64 bit) - Size of the codeblock. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 10.12.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +cblkreset_inv(bwc_coder_stripe *const cblk, const uint64 width, const uint64 height, + const uint64 depth, const uint64 dt) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i; + uint64 limit; + uint64 cblk_stripe; + uint64 x, y, z; + int64 idx_u, idx_r, idx_d, idx_l; + uint16 t; + uint8 s; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe buff; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(cblk); + + /*--------------------------------------------------------*\ + ! Calculate the number of stripes that are to be copied. ! + ! In case the number of rows is not divisible by 8, the ! + ! number of stripes is rounded up to the nearest integer. ! + \*--------------------------------------------------------*/ + cblk_stripe = ceil((double)height/4); + + /*--------------------------------------------------------*\ + ! Walk through all wavelet coefficients in the current ! + ! codeblock in a stripe pattern and save the sign and ! + ! significant magnitude bits in the bwc_coder_stripe ! + ! structure. Here, two adjacent stripes are stored ! + ! in one 8 bit integer. ! + \*--------------------------------------------------------*/ + for(t = 0, i = 0; t < dt; ++t) + { + for(z = 0; z < depth; ++z) + { + for(y = 0; y < cblk_stripe; i += width, ++y) + { + for(s = 0, limit = height - y * 4; s < 4 && s < limit; ++s) + { + for(x = 0; x < width; ++x) + { + /*--------------------------------------------------------*\ + ! Save the sample bit and context memory address in a tem- ! + ! porary variables. ! + \*--------------------------------------------------------*/ + buff.sample = cblk[x + i].sample; + buff.bit = cblk[x + i].bit; + + /*--------------------------------------------------------*\ + ! Reset the bwc_coder_stripe structure and the memory block ! + ! used to hold the sample bits of the wavelet coefficients.! + \*--------------------------------------------------------*/ + memset(&cblk[x + i], 0, sizeof(bwc_coder_stripe)); + memset(buff.bit, 0, PREC_BIT * sizeof(uint8)); + memset(buff.sample, 0, 4 * sizeof(uint64)); + + /*--------------------------------------------------------*\ + ! Store the memory address of the sample, bit and context ! + ! variables in the bwc_coder_stripe structure. ! + \*--------------------------------------------------------*/ + cblk[x + i].sample = buff.sample; + cblk[x + i].bit = buff.bit; + + /*--------------------------------------------------------*\ + ! Evaluate the appropriate index for the stripe neighbours.! + ! Neighbours that fall outside of the codeblock boundaries ! + ! are set to dummy variables to uncouple the current block ! + ! from its neighbors. ! + \*--------------------------------------------------------*/ + idx_u = (y == 0) ? -1 : (int64)(i + x - width); + idx_r = (x == width - 1) ? -2 : (int64)(i + x + 1); + idx_d = (s == limit - 1) ? -1 : (int64)(i + x + width); + idx_l = (x == 0) ? -2 : (int64)(i + x - 1); + + /*--------------------------------------------------------*\ + ! Set the state pointers. ! + \*--------------------------------------------------------*/ + cblk[x + i].stripe_u = &cblk[idx_u]; + cblk[x + i].stripe_r = &cblk[idx_r]; + cblk[x + i].stripe_d = &cblk[idx_d]; + cblk[x + i].stripe_l = &cblk[idx_l]; + } + } + } + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void cblkcopy_forward(bwc_coder_stripe *const destination, bwc_sample *const source, ! +! bwc_cblk_access *const cblkaccess, const uint64 width,! +! const uint64 height, const uint64 depth)! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function walks through the wavelet coefficients in the current codeblock in a stripe ! +! pattern and saves the sign and magnitude bits in the sign and magnitude bitfields in the ! +! bwc_coder_stripe structure. Here, the 8-bit sign and magnitude bitfields are used to store ! +! two adjacent stripes to reduce the memory footprint. Furthermore, the pointer to the neigh- ! +! boring state variables are initialized. States that fall outside of the codeblock bounda- ! +! ries are set to dummy variables to uncouple the current block from its neighbors. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! destination bwc_coder_stripe* - Pointer to the destination memory block.! +! source bwc_sample* - Pointer to the source memory block. ! +! cblkaccess bwc_cblk_access* - Structure used to directly access the ! +! parameter codeblock and subband struc- ! +! ture. ! +! width, height, depth unsigned int(64 bit) - Size of the destination memory block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +cblkcopy_forward(bwc_coder_stripe *const destination, bwc_sample *const source, + bwc_cblk_access *const cblkaccess, const uint64 width, + const uint64 height, const uint64 depth) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + bwc_raw buff, sign_mask; + uint64 bit_mask, limit; + uint64 cblk_width, cblk_height, cblk_depth, cblk_stripe; + uint64 incrX, incrY, incrZ; + uint64 i, x, y, z; + uint64 X0, Y0, Z0; + uint64 X1, Y1, Z1; + int64 idx_u, idx_r, idx_d, idx_l; + uint16 TS0, TS1; + uint16 cblk_dt; + uint16 t; + uint8 b, Kmax, s; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + bwc_float qt_step_size; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_cblk_inf *cblk_info; + bwc_sample *tmp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(destination); + assert(cblkaccess); + assert(source); + + /*--------------------------------------------------------*\ + ! Save the codeblock info structure to a temporary varia- ! + ! ble to make the code more readable. ! + \*--------------------------------------------------------*/ + cblk_info = &cblkaccess->codeblock->info; + + /*--------------------------------------------------------*\ + ! Setup a bitmask to access the sign bit position. ! + \*--------------------------------------------------------*/ + sign_mask = ~((bwc_raw)0x01 << PREC_BIT); + + /*--------------------------------------------------------*\ + ! Initialize the quantization step size and the index of ! + ! the most significant bitfield. ! + \*--------------------------------------------------------*/ + qt_step_size = cblkaccess->subband->control.qt_effective_step_size; + Kmax = 0; + + /*--------------------------------------------------------*\ + ! Save the codeblock dimensions to temporary variables to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + X0 = cblk_info->X0; + Y0 = cblk_info->Y0; + Z0 = cblk_info->Z0; + TS0 = cblk_info->TS0; + + X1 = cblk_info->X1; + Y1 = cblk_info->Y1; + Z1 = cblk_info->Z1; + TS1 = cblk_info->TS1; + + /*--------------------------------------------------------*\ + ! Calculate the width, height, depth and dt of the code- ! + ! block to be copied. ! + \*--------------------------------------------------------*/ + cblk_width = X1 - X0; + cblk_height = Y1 - Y0; + cblk_depth = Z1 - Z0; + cblk_dt = TS1 - TS0; + + /*--------------------------------------------------------*\ + ! Calculate the number of stripes that are to be copied. ! + ! In case the number of rows is not divisible by 8, the ! + ! number of stripes is rounded up to the nearest integer. ! + \*--------------------------------------------------------*/ + cblk_stripe = ceil((double)cblk_height/4); + + /*--------------------------------------------------------*\ + ! Calculate the pointer increments used to loop through ! + ! the source memory. ! + \*--------------------------------------------------------*/ + incrX = width; + incrY = width * (height - (Y1 - Y0)); + incrZ = width * height * (depth - (Z1 - Z0)); + + /*--------------------------------------------------------*\ + ! Associate the temporary pointer to the starting points ! + ! of the source memory. ! + \*--------------------------------------------------------*/ + tmp = &source[X0 + width * (Y0 + height * (Z0 + depth * TS0))]; + + /*--------------------------------------------------------*\ + ! Walk through all wavelet coefficients in the current ! + ! codeblock in a stripe pattern and save the sign and ! + ! significant magnitude bits in the bwc_coder_stripe ! + ! structure. Here, two adjacent stripes are stored ! + ! in one 8 bit integer. ! + \*--------------------------------------------------------*/ + for(t = 0, i = 0; t < cblk_dt; ++t) + { + for(z = 0; z < cblk_depth; ++z) + { + for(y = 0; y < cblk_stripe; i += cblk_width, ++y) + { + /*--------------------------------------------------------*\ + ! Initialize the stripe bit masks to the first stripe posi-! + ! tion in the sign, state and sample variables. ! + \*--------------------------------------------------------*/ + bit_mask = 0x08; + + for(s = 0, limit = cblk_height - y * 4; s < 4 && s < limit; ++s) + { + for(x = 0; x < cblk_width; ++x) + { + /*--------------------------------------------------------*\ + ! Save the sign bit of the current wavelet coefficient in ! + ! the appropriate position of the sign field. ! + \*--------------------------------------------------------*/ + destination[x + i].xi |= bit_mask * (tmp[x].raw / ~sign_mask); + + /*--------------------------------------------------------*\ + ! Calculate the absolute value of the wavelet coefficient ! + ! and store the quantized value in the temporary buffer. ! + \*--------------------------------------------------------*/ + tmp[x].raw &= sign_mask; + buff = (bwc_raw)(tmp[x].f / qt_step_size); + + /*--------------------------------------------------------*\ + ! Save the unsigned wavelet coefficient for distortion ! + ! calculation. ! + \*--------------------------------------------------------*/ + destination[x + i].sample[3 - s] = buff; + + /*--------------------------------------------------------*\ + ! set the bitfield index b to zero. ! + \*--------------------------------------------------------*/ + b = 0; + + /*--------------------------------------------------------*\ + ! Save the significant bits of the current wavelet coeffi- ! + ! cient in the appropriate bitfield and stripe. ! + \*--------------------------------------------------------*/ + while(buff) + { + destination[x + i].bit[b] |= bit_mask * (buff & 0x01); + buff >>= 1; + b++; + } + + /*--------------------------------------------------------*\ + ! Update the index of the most significant bitfield. ! + \*--------------------------------------------------------*/ + Kmax = MAX(Kmax, b); + + /*--------------------------------------------------------*\ + ! Evaluate the appropriate index for the stripe neighbours ! + ! Neighbours that fall outside of the codeblock boundaries ! + ! are set to dummy variables to uncouple the current block ! + ! from its neighbors. ! + \*--------------------------------------------------------*/ + idx_u = (y == 0) ? -1 : (int64)(i + x - cblk_width); + idx_r = (x == cblk_width - 1) ? -2 : (int64)(i + x + 1); + idx_d = (s == limit - 1) ? -1 : (int64)(i + x + cblk_width); + idx_l = (x == 0) ? -2 : (int64)(i + x - 1); + + /*--------------------------------------------------------*\ + ! Set the state pointers. ! + \*--------------------------------------------------------*/ + destination[x + i].stripe_u = &destination[idx_u]; + destination[x + i].stripe_r = &destination[idx_r]; + destination[x + i].stripe_d = &destination[idx_d]; + destination[x + i].stripe_l = &destination[idx_l]; + } + /*--------------------------------------------------------*\ + ! Increment the stripe bit mask to the next stripe posi- ! + ! tion slice and increment the temporary data pointer to ! + ! the next row. ! + \*--------------------------------------------------------*/ + bit_mask >>= 1; + tmp += incrX; + } + } + /*--------------------------------------------------------*\ + ! Increment to the next column. ! + \*--------------------------------------------------------*/ + tmp += incrY; + } + /*--------------------------------------------------------*\ + ! Increment to the next spatial slice. ! + \*--------------------------------------------------------*/ + tmp += incrZ; + } + /*--------------------------------------------------------*\ + ! Save the most significant bitfield of the current sub- ! + ! band in the appropriate subband structure. ! + \*--------------------------------------------------------*/ + cblkaccess->codeblock->control.K = Kmax; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void cblkcopy_inverse(bwc_coder_stripe *const destination, bwc_sample *const source, ! +! bwc_cblk_access *const cblkaccess, const uint64 width,! +! const uint64 height, const uint64 depth)! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to copy the decompressed wavelet coefficients from the codeblock ! +! structure to the parameter data memory block. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! destination bwc_coder_stripe* - Pointer to the destination memory block.! +! source bwc_sample* - Pointer to the source memory block. ! +! cblkaccess bwc_cblk_access* - Structure used to directly access the ! +! parameter codeblock and subband struc- ! +! ture. ! +! width, height, depth unsigned int(64 bit) - Size of the destination memory block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +cblkcopy_inverse(bwc_coder_stripe *const source, bwc_sample *const destination, + bwc_cblk_access *const cblkaccess, const uint64 width, + const uint64 height, const uint64 depth) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 cblk_width, cblk_height, cblk_depth, cblk_stripe; + uint64 bit_shift, buff, limit; + uint64 incrX, incrY, incrZ; + uint64 i, x, y, z; + uint64 X0, Y0, Z0; + uint64 X1, Y1, Z1; + uint16 TS0, TS1; + uint16 cblk_dt; + uint16 t; + uint8 bitplane; + uint8 codingpass; + uint8 s; + int8 b; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + bwc_float qt_step_size; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_cblk_inf *cblk_info; + bwc_sample *tmp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(destination); + assert(cblkaccess); + assert(source); + + /*--------------------------------------------------------*\ + ! Save the codeblock info structure to a temporary varia- ! + ! ble to make the code more readable. ! + \*--------------------------------------------------------*/ + cblk_info = &cblkaccess->codeblock->info; + + /*--------------------------------------------------------*\ + ! Initialize the quantization step size and the index of ! + ! the most significant bitfield. ! + \*--------------------------------------------------------*/ + qt_step_size = cblkaccess->subband->control.qt_effective_step_size; + + /*--------------------------------------------------------*\ + ! Safe the last bitplane and codingpass to temporary vari- ! + ! able to make the code more readable. ! + \*--------------------------------------------------------*/ + bitplane = source->bitplane; + codingpass = source->codingpass; + + /*--------------------------------------------------------*\ + ! Save the codeblock dimensions to temporary variables to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + X0 = cblk_info->X0; + Y0 = cblk_info->Y0; + Z0 = cblk_info->Z0; + TS0 = cblk_info->TS0; + + X1 = cblk_info->X1; + Y1 = cblk_info->Y1; + Z1 = cblk_info->Z1; + TS1 = cblk_info->TS1; + + /*--------------------------------------------------------*\ + ! Calculate the width, height, depth and dt of the code- ! + ! block to be copied. ! + \*--------------------------------------------------------*/ + cblk_width = X1 - X0; + cblk_height = Y1 - Y0; + cblk_depth = Z1 - Z0; + cblk_dt = TS1 - TS0; + + /*--------------------------------------------------------*\ + ! Calculate the number of stripes that are to be copied. ! + ! In case the number of rows is not divisible by 8, the ! + ! number of stripes is rounded up to the nearest integer. ! + \*--------------------------------------------------------*/ + cblk_stripe = ceil((double)cblk_height/4); + + /*--------------------------------------------------------*\ + ! Calculate the pointer increments used to loop through ! + ! the destination memory. ! + \*--------------------------------------------------------*/ + incrX = width; + incrY = width * (height - (Y1 - Y0)); + incrZ = width * height * (depth - (Z1 - Z0)); + + /*--------------------------------------------------------*\ + ! Associate the temporary pointer to the starting points ! + ! of the destination memory. ! + \*--------------------------------------------------------*/ + tmp = &destination[X0 + width * (Y0 + height * (Z0 + depth * TS0))]; + + /*--------------------------------------------------------*\ + ! Walk through all wavelet coefficients in the current ! + ! codeblock in a stripe pattern and save the sign and ! + ! significant magnitude bits in the bwc_coder_stripe ! + ! structure. Here, two adjacent stripes are stored ! + ! in one 8 bit integer. ! + \*--------------------------------------------------------*/ + for(t = 0, i = 0; t < cblk_dt; ++t) + { + for(z = 0; z < cblk_depth; ++z) + { + for(y = 0; y < cblk_stripe; i += cblk_width, ++y) + { + /*--------------------------------------------------------*\ + ! Initialize the stripe bit masks to the first stripe posi-! + ! tion in the sign, state and sample variables. ! + \*--------------------------------------------------------*/ + bit_shift = 0x03; + + for(s = 0, limit = cblk_height - y * 4; s < 4 && s < limit; ++s) + { + for(x = 0; x < cblk_width; ++x) + { + /*--------------------------------------------------------*\ + ! Save the significant bits of the current wavelet coeffi- ! + ! cient in the appropriate bitfield and stripe. ! + \*--------------------------------------------------------*/ + for(b = PREC_BIT, buff = 0; b --> 0;) + { + buff <<= 1; + buff |= (source[x + i].bit[b] >> bit_shift) & 0x01; + } + + /*--------------------------------------------------------*\ + ! Calculate the absolute value of the wavelet coefficient ! + ! and store the quantized value in the temporary buffer. ! + \*--------------------------------------------------------*/ + if(buff) + { + tmp[x].f = (bwc_float)buff; + tmp[x].f += (1UL << (bitplane + ((!codingpass || ((source[x + i].pi >> bit_shift) & 0x01)) ? 0 : 1))) * 0.475f; + tmp[x].f *= qt_step_size; + tmp[x].raw |= SIGN * ((source[x + i].xi >> bit_shift) & 0x01); + } + } + + /*--------------------------------------------------------*\ + ! Increment the stripe bit mask to the next stripe posi- ! + ! tion slice and increment the temporary data pointer to ! + ! the next row. ! + \*--------------------------------------------------------*/ + bit_shift--; + tmp += incrX; + } + } + /*--------------------------------------------------------*\ + ! Increment to the next column. ! + \*--------------------------------------------------------*/ + tmp += incrY; + } + /*--------------------------------------------------------*\ + ! Increment to the next spatial slice. ! + \*--------------------------------------------------------*/ + tmp += incrZ; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uint64 +significance_propagation_enc_pass(bwc_coder *const coder, const int8 b) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i, j; + uint64 k, x; + int64 mse; + uint16 k_h, k_v, k_d; + uint16 k_sig; + uint16 xi_h, xi_v; + uint8 bit_mask, stripe_mask; + uint8 dist_shift, dist_corr, l; + uint8 bit; + uint8 rest; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe *stripe; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + + mse = 0; + stripe = coder->data; + rest = 4 - (coder->height & 0x03); + stripe_mask = ~((0x0F >> ((coder->height & 0x03))) | 0xF0); + dist_shift = (b < DISTORTION_MANTISSA) ? 0 : (b - DISTORTION_MANTISSA); + dist_corr = (b < DISTORTION_MANTISSA) ? (DISTORTION_MANTISSA - b) : 0; + + for(i = 0, k = 0; i < coder->no_slice; ++i) + { + for(j = 0; j < coder->no_full_stripe; ++j) + { + for(x = 0; x < coder->width; ++x, ++k) + { + if(stripe[k].sigma^0xF) + { + for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> 0; bit_mask >>= 1) + { + if(!(stripe[k].sigma & bit_mask)) + { + k_h = (stripe[k].stripe_l->sigma & bit_mask) + (stripe[k].stripe_r->sigma & bit_mask); + + k_v = ((bit_mask & (stripe[k].sigma >> 1)) + (bit_mask & (stripe[k].sigma << 1))); + + k_d = ((bit_mask & (stripe[k].stripe_l->sigma >> 1)) + (bit_mask & (stripe[k].stripe_l->sigma << 1)) + + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) + (bit_mask & (stripe[k].stripe_r->sigma << 1))); + + if(l == 3) + { + k_v += ((0x01 & stripe[k].stripe_u->sigma) << 3); + k_d += ((0x01 & stripe[k].stripe_u->stripe_l->sigma) + + (0x01 & stripe[k].stripe_u->stripe_r->sigma)) << 3; + } + else if(l == 0) + { + k_v += ((0x08 & stripe[k].stripe_d->sigma) >> 3); + k_d += ((0x08 & stripe[k].stripe_d->stripe_l->sigma) + + (0x08 & stripe[k].stripe_d->stripe_r->sigma)) >> 3; + } + + k_sig = ((15 * k_h + 5 * k_v + k_d) >> l); + + if(k_sig) + { + bit_encode(coder->bitcoder, (uchar)((bit >> l) & 0x01), coder->sig2context[k_sig]); + + if(bit & bit_mask) + { + xi_h = ((bit_mask & stripe[k].stripe_l->sigma) | ((bit_mask & stripe[k].stripe_l->xi) << 2) | + ((bit_mask & stripe[k].stripe_r->sigma) << 1) | ((bit_mask & stripe[k].stripe_r->xi) << 3)) >> l; + + xi_v = ((bit_mask & (stripe[k].sigma >> 1)) | ((bit_mask & (stripe[k].xi >> 1)) << 2) | + ((bit_mask & (stripe[k].sigma << 1)) << 1) | ((bit_mask & (stripe[k].xi << 1)) << 3)) >> l; + + if(l == 3) + { + xi_v |= ((0x01 & stripe[k].stripe_u->sigma) | ((0x01 & stripe[k].stripe_u->xi) << 2)); + } + else if(l == 0) + { + xi_v |= (((0x08 & stripe[k].stripe_d->sigma) >> 2) | (0x08 & stripe[k].stripe_d->xi)); + } + + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + bit_encode(coder->bitcoder, (uchar)(((bit_mask & stripe[k].xi) >> l)^XI2CONT[(xi_h << 2) | xi_v][1]), + XI2CONT[(xi_h << 2) | xi_v][0]); + + mse += DISTORTION_TS_LUT[((stripe[k].sample[l] >> dist_shift) << dist_corr) & 0x1F]; + stripe[k].sigma |= bit_mask; + } + + stripe[k].pi |= bit_mask; + } + } + else + { + stripe[k].pi ^= (stripe[k].pi & bit_mask); + } + } + } + else + { + stripe[k].pi = 0; + } + } + } + + if(rest < 4) + { + for(x = 0; x < coder->width; ++x, ++k) + { + if((stripe[k].sigma^0xF) & stripe_mask) + { + for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> rest; bit_mask >>= 1) + { + if(!(stripe[k].sigma & bit_mask)) + { + k_h = (stripe[k].stripe_l->sigma & bit_mask) + (stripe[k].stripe_r->sigma & bit_mask); + + k_v = ((bit_mask & (stripe[k].sigma >> 1)) + (bit_mask & (stripe[k].sigma << 1))); + + k_d = ((bit_mask & (stripe[k].stripe_l->sigma >> 1)) + (bit_mask & (stripe[k].stripe_l->sigma << 1)) + + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) + (bit_mask & (stripe[k].stripe_r->sigma << 1))); + + if(l == 3) + { + k_v += ((0x01 & stripe[k].stripe_u->sigma) << 3); + k_d += ((0x01 & stripe[k].stripe_u->stripe_l->sigma) + + (0x01 & stripe[k].stripe_u->stripe_r->sigma)) << 3; + } + + k_sig = ((15 * k_h + 5 * k_v + k_d) >> l); + + if(k_sig && (stripe[k].sigma^bit_mask)) + { + bit_encode(coder->bitcoder, (uchar)((bit >> l) & 0x01), coder->sig2context[k_sig]); + + if(bit & bit_mask) + { + xi_h = ((bit_mask & stripe[k].stripe_l->sigma) | ((bit_mask & stripe[k].stripe_l->xi) << 2) | + ((bit_mask & stripe[k].stripe_r->sigma) << 1) | ((bit_mask & stripe[k].stripe_r->xi) << 3)) >> l; + + xi_v = ((bit_mask & (stripe[k].sigma >> 1)) | ((bit_mask & (stripe[k].xi >> 1)) << 2) | + ((bit_mask & (stripe[k].sigma << 1)) << 1) | ((bit_mask & (stripe[k].xi << 1)) << 3)) >> l; + + if(l == 3) + { + xi_v |= ((0x01 & stripe[k].stripe_u->sigma) | ((0x01 & stripe[k].stripe_u->xi) << 2)); + } + + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + bit_encode(coder->bitcoder, (uchar)(((bit_mask & stripe[k].xi) >> l)^XI2CONT[(xi_h << 2) | xi_v][1]), + XI2CONT[(xi_h << 2) | xi_v][0]); + + mse += DISTORTION_TS_LUT[((stripe[k].sample[l] >> dist_shift) << dist_corr) & 0x1F]; + stripe[k].sigma |= bit_mask; + } + + stripe[k].pi |= bit_mask; + } + } + else + { + stripe[k].pi ^= (stripe[k].pi & bit_mask); + } + } + } + else + { + stripe[k].pi = 0; + } + } + } + } + return mse; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uint64 +magnitude_refinement_enc_pass(bwc_coder *const coder, const int8 b) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i, j; + uint64 k, x; + int64 mse; + uint16 k_mag; + uint8 bit_mask, stripe_mask; + uint8 dist_shift, dist_corr, l; + uint8 bit, sig; + uint8 rest; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe *stripe; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + + mse = 0; + stripe = coder->data; + rest = 4 - (coder->height & 0x03); + stripe_mask = ~((0x0F >> ((coder->height & 0x03))) | 0xF0); + dist_shift = (b < DISTORTION_MANTISSA) ? 0 : (b - DISTORTION_MANTISSA); + dist_corr = (b < DISTORTION_MANTISSA) ? (DISTORTION_MANTISSA - b) : 0; + + for(i = 0, k = 0; i < coder->no_slice; ++i) + { + for(j = 0; j < coder->no_full_stripe; ++j) + { + for(x = 0; x < coder->width; ++x, ++k) + { + sig = stripe[k].sigma & (~stripe[k].pi); + + for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> 0; bit_mask >>= 1) + { + if(sig & bit_mask) + { + k_mag = CONTEXT_MAG; + + if(stripe[k].delta & bit_mask) + { + k_mag += 2; + } + else + { + if((bit_mask & (stripe[k].sigma >> 1)) || (bit_mask & (stripe[k].sigma << 1)) || + (stripe[k].stripe_l->sigma & bit_mask) || (stripe[k].stripe_r->sigma & bit_mask) || + (bit_mask & (stripe[k].stripe_l->sigma >> 1)) || (bit_mask & (stripe[k].stripe_l->sigma << 1)) || + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) || (bit_mask & (stripe[k].stripe_r->sigma << 1))) + { + k_mag += 1; + } + else if((l == 3) && ((0x08 & (stripe[k].stripe_u->sigma << 3)) + || (0x08 & (stripe[k].stripe_u->stripe_l->sigma << 3)) + || (0x08 & (stripe[k].stripe_u->stripe_r->sigma << 3)))) + { + k_mag += 1; + } + else if((l == 0) && ((0x01 & (stripe[k].stripe_d->sigma >> 3)) + || (0x01 & (stripe[k].stripe_d->stripe_l->sigma >> 3)) + || (0x01 & (stripe[k].stripe_d->stripe_r->sigma >> 3)))) + { + k_mag += 1; + } + } + + bit_encode(coder->bitcoder, (uchar)((bit >> l) & 0x01), k_mag); + + mse += DISTORTION_TM_LUT[((stripe[k].sample[l] >> dist_shift) << dist_corr) & 0x3F]; + stripe[k].delta |= bit_mask; + } + } + } + } + + if(rest < 4) + { + for(x = 0; x < coder->width; ++x, ++k) + { + sig = (stripe[k].sigma & (~stripe[k].pi)) & stripe_mask; + + for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> rest; bit_mask >>= 1) + { + if(sig & bit_mask) + { + k_mag = CONTEXT_MAG; + + if(stripe[k].delta & bit_mask) + { + k_mag += 2; + } + else + { + if((bit_mask & (stripe[k].sigma >> 1)) || (bit_mask & (stripe[k].sigma << 1)) || + (stripe[k].stripe_l->sigma & bit_mask) || (stripe[k].stripe_r->sigma & bit_mask) || + (bit_mask & (stripe[k].stripe_l->sigma >> 1)) || (bit_mask & (stripe[k].stripe_l->sigma << 1)) || + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) || (bit_mask & (stripe[k].stripe_r->sigma << 1))) + { + k_mag += 1; + } + else if((l == 3) && ((0x08 & (stripe[k].stripe_u->sigma << 3)) + || (0x08 & (stripe[k].stripe_u->stripe_l->sigma << 3)) + || (0x08 & (stripe[k].stripe_u->stripe_r->sigma << 3)))) + { + k_mag += 1; + } + } + + bit_encode(coder->bitcoder, (uchar)((bit >> l) & 0x01), k_mag); + + mse += DISTORTION_TM_LUT[((stripe[k].sample[l] >> dist_shift) << dist_corr) & 0x3F]; + stripe[k].delta |= bit_mask; + } + } + } + } + } + return mse; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uint64 +cleanup_enc_pass(bwc_coder *const coder, const int8 b) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i, j; + uint64 k, x; + int64 mse; + uint16 k_h, k_v, k_d; + uint16 xi_h, xi_v; + uint8 bit_mask, l; + uint8 dist_shift, dist_corr; + uint8 bit; + uint8 rest; + int8 r; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe *stripe; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + + mse = 0; + stripe = coder->data; + rest = 4 - (coder->height & 0x03); + dist_shift = (b < DISTORTION_MANTISSA) ? 0 : (b - DISTORTION_MANTISSA); + dist_corr = (b < DISTORTION_MANTISSA) ? (DISTORTION_MANTISSA - b) : 0; + + for(i = 0, k = 0; i < coder->no_slice; ++i) + { + for(j = 0; j < coder->no_full_stripe; ++j) + { + for(x = 0; x < coder->width; ++x, ++k) + { + r = -1; + + if(!(0x08 & stripe[k].stripe_d->stripe_l->sigma) && !(0x08 & stripe[k].stripe_d->sigma) && + !(0x08 & stripe[k].stripe_d->stripe_r->sigma) && !(0x01 & stripe[k].stripe_u->sigma) && + !(0x01 & stripe[k].stripe_u->stripe_l->sigma) && !stripe[k].stripe_l->sigma && + !(0x01 & stripe[k].stripe_u->stripe_r->sigma) && !stripe[k].stripe_r->sigma && + !stripe[k].sigma) + { + bit = stripe[k].bit[b]; + if(bit) + { + r = bit | (bit >> 1); + r |= r >> 2; + r = DISTORTION_LZ_LUT[r]; + + bit_encode(coder->bitcoder, (uchar)1, CONTEXT_RUN); + bit_encode(coder->bitcoder, (uchar)r >> 1, CONTEXT_UNI); + bit_encode(coder->bitcoder, (uchar)r&0x01, CONTEXT_UNI); + } + else + { + r = 4; + bit_encode(coder->bitcoder, (uchar)0, CONTEXT_RUN); + } + } + + for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> 0; bit_mask >>= 1) + { + if(!(stripe[k].sigma & bit_mask) && !(stripe[k].pi & bit_mask)) + { + if(r >= 0) + { + r--; + } + else + { + k_h = (stripe[k].stripe_l->sigma & bit_mask) + (stripe[k].stripe_r->sigma & bit_mask); + + k_v = ((bit_mask & (stripe[k].sigma >> 1)) + (bit_mask & (stripe[k].sigma << 1))); + + k_d = ((bit_mask & (stripe[k].stripe_l->sigma >> 1)) + (bit_mask & (stripe[k].stripe_l->sigma << 1)) + + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) + (bit_mask & (stripe[k].stripe_r->sigma << 1))); + + if(l == 3) + { + k_v += ((0x01 & stripe[k].stripe_u->sigma) << 3); + k_d += ((0x01 & stripe[k].stripe_u->stripe_l->sigma) + + (0x01 & stripe[k].stripe_u->stripe_r->sigma)) << 3; + } + else if(l == 0) + { + k_v += ((0x08 & stripe[k].stripe_d->sigma) >> 3); + k_d += ((0x08 & stripe[k].stripe_d->stripe_l->sigma) + + (0x08 & stripe[k].stripe_d->stripe_r->sigma)) >> 3; + } + + bit_encode(coder->bitcoder, (uchar)((bit >> l) & 0x01), coder->sig2context[(15 * k_h + 5 * k_v + k_d) >> l]); + } + if(bit & bit_mask) + { + xi_h = ((bit_mask & stripe[k].stripe_l->sigma) | ((bit_mask & stripe[k].stripe_l->xi) << 2) | + ((bit_mask & stripe[k].stripe_r->sigma) << 1) | ((bit_mask & stripe[k].stripe_r->xi) << 3)) >> l; + + xi_v = ((bit_mask & (stripe[k].sigma >> 1)) | ((bit_mask & (stripe[k].xi >> 1)) << 2) | + ((bit_mask & (stripe[k].sigma << 1)) << 1) | ((bit_mask & (stripe[k].xi << 1)) << 3)) >> l; + + if(l == 3) + { + xi_v |= ((0x01 & stripe[k].stripe_u->sigma) | ((0x01 & stripe[k].stripe_u->xi) << 2)); + } + else if(l == 0) + { + xi_v |= (((0x08 & stripe[k].stripe_d->sigma) >> 2) | (0x08 & stripe[k].stripe_d->xi)); + } + + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + bit_encode(coder->bitcoder, (uchar)(((bit_mask & stripe[k].xi) >> l)^XI2CONT[(xi_h << 2) | xi_v][1]), + XI2CONT[(xi_h << 2) | xi_v][0]); + + mse += DISTORTION_TS_LUT[((stripe[k].sample[l] >> dist_shift) << dist_corr) & 0x1F]; + stripe[k].sigma |= bit_mask; + } + } + } + } + } + + if(rest < 4) + { + for(x = 0; x < coder->width; ++x, ++k) + { + for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> rest; bit_mask >>= 1) + { + if(!(stripe[k].sigma & bit_mask) && !(stripe[k].pi & bit_mask)) + { + k_h = (stripe[k].stripe_l->sigma & bit_mask) + (stripe[k].stripe_r->sigma & bit_mask); + + k_v = ((bit_mask & (stripe[k].sigma >> 1)) + (bit_mask & (stripe[k].sigma << 1))); + + k_d = ((bit_mask & (stripe[k].stripe_l->sigma >> 1)) + (bit_mask & (stripe[k].stripe_l->sigma << 1)) + + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) + (bit_mask & (stripe[k].stripe_r->sigma << 1))); + + if(l == 3) + { + k_v += ((0x01 & stripe[k].stripe_u->sigma) << 3); + k_d += ((0x01 & stripe[k].stripe_u->stripe_l->sigma) + + (0x01 & stripe[k].stripe_u->stripe_r->sigma)) << 3; + } + + bit_encode(coder->bitcoder, (uchar)((bit >> l) & 0x01), coder->sig2context[(15 * k_h + 5 * k_v + k_d) >> l]); + + if(bit & bit_mask) + { + xi_h = ((bit_mask & stripe[k].stripe_l->sigma) | ((bit_mask & stripe[k].stripe_l->xi) << 2) | + ((bit_mask & stripe[k].stripe_r->sigma) << 1) | ((bit_mask & stripe[k].stripe_r->xi) << 3)) >> l; + + xi_v = ((bit_mask & (stripe[k].sigma >> 1)) | ((bit_mask & (stripe[k].xi >> 1)) << 2) | + ((bit_mask & (stripe[k].sigma << 1)) << 1) | ((bit_mask & (stripe[k].xi << 1)) << 3)) >> l; + + if(l == 3) + { + xi_v |= ((0x01 & stripe[k].stripe_u->sigma) | ((0x01 & stripe[k].stripe_u->xi) << 2)); + } + + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + bit_encode(coder->bitcoder, (uchar)(((bit_mask & stripe[k].xi) >> l)^XI2CONT[(xi_h << 2) | xi_v][1]), + XI2CONT[(xi_h << 2) | xi_v][0]); + + mse += DISTORTION_TS_LUT[((stripe[k].sample[l] >> dist_shift) << dist_corr) & 0x1F]; + stripe[k].sigma |= bit_mask; + } + } + } + } + } + } + return mse; +} + + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +significance_propagation_dec_pass(bwc_coder *const coder, const int8 b) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i, j; + uint64 k, x; + uint16 k_h, k_v, k_d; + uint16 k_sig; + uint16 xi_h, xi_v; + uint8 bit_mask, stripe_mask; + uint8 l; + uint8 bit; + uint8 rest; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe *stripe; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + + stripe = coder->data; + stripe_mask = ~((0x0F >> ((coder->height & 0x03))) | 0xF0); + rest = 4 - (coder->height & 0x03); + + for(i = 0, k = 0; i < coder->no_slice; ++i) + { + for(j = 0; j < coder->no_full_stripe; ++j) + { + for(x = 0; x < coder->width; ++x, ++k) + { + if(stripe[k].sigma^0xF) + { + for(bit_mask = 0x08, l = 4; l --> 0; bit_mask >>= 1) + { + if(!(stripe[k].sigma & bit_mask)) + { + k_h = (stripe[k].stripe_l->sigma & bit_mask) + (stripe[k].stripe_r->sigma & bit_mask); + + k_v = ((bit_mask & (stripe[k].sigma >> 1)) + (bit_mask & (stripe[k].sigma << 1))); + + k_d = ((bit_mask & (stripe[k].stripe_l->sigma >> 1)) + (bit_mask & (stripe[k].stripe_l->sigma << 1)) + + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) + (bit_mask & (stripe[k].stripe_r->sigma << 1))); + + if(l == 3) + { + k_v += ((0x01 & stripe[k].stripe_u->sigma) << 3); + k_d += ((0x01 & stripe[k].stripe_u->stripe_l->sigma) + + (0x01 & stripe[k].stripe_u->stripe_r->sigma)) << 3; + } + else if(l == 0) + { + k_v += ((0x08 & stripe[k].stripe_d->sigma) >> 3); + k_d += ((0x08 & stripe[k].stripe_d->stripe_l->sigma) + + (0x08 & stripe[k].stripe_d->stripe_r->sigma)) >> 3; + } + + k_sig = ((15 * k_h + 5 * k_v + k_d) >> l); + + if(k_sig) + { + bit = bit_decode(coder->bitcoder, coder->sig2context[k_sig]); + + if(bit) + { + stripe[k].bit[b] |= (bit << l); + + xi_h = ((bit_mask & stripe[k].stripe_l->sigma) | ((bit_mask & stripe[k].stripe_l->xi) << 2) | + ((bit_mask & stripe[k].stripe_r->sigma) << 1) | ((bit_mask & stripe[k].stripe_r->xi) << 3)) >> l; + + xi_v = ((bit_mask & (stripe[k].sigma >> 1)) | ((bit_mask & (stripe[k].xi >> 1)) << 2) | + ((bit_mask & (stripe[k].sigma << 1)) << 1) | ((bit_mask & (stripe[k].xi << 1)) << 3)) >> l; + + if(l == 3) + { + xi_v |= ((0x01 & stripe[k].stripe_u->sigma) | ((0x01 & stripe[k].stripe_u->xi) << 2)); + } + else if(l == 0) + { + xi_v |= (((0x08 & stripe[k].stripe_d->sigma) >> 2) | (0x08 & stripe[k].stripe_d->xi)); + } + + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + stripe[k].xi |= ((XI2CONT[(xi_h << 2) | xi_v][1] ^ bit_decode(coder->bitcoder, XI2CONT[(xi_h << 2) | xi_v][0])) << l); + + stripe[k].sigma |= bit_mask; + } + + stripe[k].pi |= bit_mask; + } + } + else + { + stripe[k].pi ^= (stripe[k].pi & bit_mask); + } + } + } + else + { + stripe[k].pi = 0; + } + } + } + + if(rest < 4) + { + for(x = 0; x < coder->width; ++x, ++k) + { + if((stripe[k].sigma^0xF) & stripe_mask) + { + for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> rest; bit_mask >>= 1) + { + if(!(stripe[k].sigma & bit_mask)) + { + k_h = (stripe[k].stripe_l->sigma & bit_mask) + (stripe[k].stripe_r->sigma & bit_mask); + + k_v = ((bit_mask & (stripe[k].sigma >> 1)) + (bit_mask & (stripe[k].sigma << 1))); + + k_d = ((bit_mask & (stripe[k].stripe_l->sigma >> 1)) + (bit_mask & (stripe[k].stripe_l->sigma << 1)) + + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) + (bit_mask & (stripe[k].stripe_r->sigma << 1))); + + if(l == 3) + { + k_v += ((0x01 & stripe[k].stripe_u->sigma) << 3); + k_d += ((0x01 & stripe[k].stripe_u->stripe_l->sigma) + + (0x01 & stripe[k].stripe_u->stripe_r->sigma)) << 3; + } + + k_sig = ((15 * k_h + 5 * k_v + k_d) >> l); + + if(k_sig && (stripe[k].sigma^bit_mask)) + { + bit = bit_decode(coder->bitcoder, coder->sig2context[k_sig]); + + if(bit) + { + stripe[k].bit[b] |= (bit << l); + + xi_h = ((bit_mask & stripe[k].stripe_l->sigma) | ((bit_mask & stripe[k].stripe_l->xi) << 2) | + ((bit_mask & stripe[k].stripe_r->sigma) << 1) | ((bit_mask & stripe[k].stripe_r->xi) << 3)) >> l; + + xi_v = ((bit_mask & (stripe[k].sigma >> 1)) | ((bit_mask & (stripe[k].xi >> 1)) << 2) | + ((bit_mask & (stripe[k].sigma << 1)) << 1) | ((bit_mask & (stripe[k].xi << 1)) << 3)) >> l; + + if(l == 3) + { + xi_v |= ((0x01 & stripe[k].stripe_u->sigma) | ((0x01 & stripe[k].stripe_u->xi) << 2)); + } + + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + stripe[k].xi |= ((XI2CONT[(xi_h << 2) | xi_v][1] ^ bit_decode(coder->bitcoder, XI2CONT[(xi_h << 2) | xi_v][0])) << l); + + stripe[k].sigma |= bit_mask; + } + + stripe[k].pi |= bit_mask; + } + } + else + { + stripe[k].pi ^= (stripe[k].pi & bit_mask); + } + } + } + else + { + stripe[k].pi = 0; + } + } + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +magnitude_refinement_dec_pass(bwc_coder *const coder, const int8 b) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i, j; + uint64 k, x; + uint16 k_mag; + uint8 bit_mask, stripe_mask; + uint8 l; + uint8 sig; + uint8 rest; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe *stripe; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + + stripe = coder->data; + stripe_mask= ~((0x0F >> ((coder->height & 0x03))) | 0xF0); + rest = 4 - (coder->height & 0x03); + + for(i = 0, k = 0; i < coder->no_slice; ++i) + { + for(j = 0; j < coder->no_full_stripe; ++j) + { + for(x = 0; x < coder->width; ++x, ++k) + { + sig = stripe[k].sigma & (~stripe[k].pi); + + for(bit_mask = 0x08, l = 4; l --> 0; bit_mask >>= 1) + { + if(sig & bit_mask) + { + k_mag = CONTEXT_MAG; + + if(stripe[k].delta & bit_mask) + { + k_mag += 2; + } + else + { + if((bit_mask & (stripe[k].sigma >> 1)) || (bit_mask & (stripe[k].sigma << 1)) || + (stripe[k].stripe_l->sigma & bit_mask) || (stripe[k].stripe_r->sigma & bit_mask) || + (bit_mask & (stripe[k].stripe_l->sigma >> 1)) || (bit_mask & (stripe[k].stripe_l->sigma << 1)) || + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) || (bit_mask & (stripe[k].stripe_r->sigma << 1))) + { + k_mag += 1; + } + else if((l == 3) && ((0x08 & (stripe[k].stripe_u->sigma << 3)) + || (0x08 & (stripe[k].stripe_u->stripe_l->sigma << 3)) + || (0x08 & (stripe[k].stripe_u->stripe_r->sigma << 3)))) + { + k_mag += 1; + } + else if((l == 0) && ((0x01 & (stripe[k].stripe_d->sigma >> 3)) + || (0x01 & (stripe[k].stripe_d->stripe_l->sigma >> 3)) + || (0x01 & (stripe[k].stripe_d->stripe_r->sigma >> 3)))) + { + k_mag += 1; + } + } + + stripe[k].bit[b] |= (bit_decode(coder->bitcoder, k_mag) << l); + + stripe[k].delta |= bit_mask; + } + } + } + } + + if(rest < 4) + { + for(x = 0; x < coder->width; ++x, ++k) + { + sig = (stripe[k].sigma & (~stripe[k].pi)) & stripe_mask; + + for(bit_mask = 0x08, l = 4; l --> rest; bit_mask >>= 1) + { + if(sig & bit_mask) + { + k_mag = CONTEXT_MAG; + + if(stripe[k].delta & bit_mask) + { + k_mag += 2; + } + else + { + if((bit_mask & (stripe[k].sigma >> 1)) || (bit_mask & (stripe[k].sigma << 1)) || + (stripe[k].stripe_l->sigma & bit_mask) || (stripe[k].stripe_r->sigma & bit_mask) || + (bit_mask & (stripe[k].stripe_l->sigma >> 1)) || (bit_mask & (stripe[k].stripe_l->sigma << 1)) || + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) || (bit_mask & (stripe[k].stripe_r->sigma << 1))) + { + k_mag += 1; + } + else if((l == 3) && ((0x08 & (stripe[k].stripe_u->sigma << 3)) + || (0x08 & (stripe[k].stripe_u->stripe_l->sigma << 3)) + || (0x08 & (stripe[k].stripe_u->stripe_r->sigma << 3)))) + { + k_mag += 1; + } + } + + stripe[k].bit[b] |= (bit_decode(coder->bitcoder, k_mag) << l); + + stripe[k].delta |= bit_mask; + } + } + } + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +cleanup_dec_pass(bwc_coder *const coder, const int8 b) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i, j; + uint64 k, x; + uint16 k_h, k_v, k_d; + uint16 xi_h, xi_v; + uint8 bit_mask, l; + uint8 bit; + uint8 rest; + int8 r; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe *stripe; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + + rest = 4 - (coder->height & 0x03); + stripe = coder->data; + + for(i = 0, k = 0; i < coder->no_slice; ++i) + { + for(j = 0; j < coder->no_full_stripe; ++j) + { + for(x = 0; x < coder->width; ++x, ++k) + { + bit = 0; + r = -1; + + if(!(0x08 & stripe[k].stripe_d->stripe_l->sigma) && !(0x08 & stripe[k].stripe_d->sigma) && + !(0x08 & stripe[k].stripe_d->stripe_r->sigma) && !(0x01 & stripe[k].stripe_u->sigma) && + !(0x01 & stripe[k].stripe_u->stripe_l->sigma) && !stripe[k].stripe_l->sigma && + !(0x01 & stripe[k].stripe_u->stripe_r->sigma) && !stripe[k].stripe_r->sigma && + !stripe[k].sigma) + { + if(bit_decode(coder->bitcoder, CONTEXT_RUN)) + { + r = bit_decode(coder->bitcoder, CONTEXT_UNI); + r = (r << 1) + bit_decode(coder->bitcoder, CONTEXT_UNI); + bit |= (0x08 >> r); + } + else + { + r = 4; + } + } + + for(bit_mask = 0x08, l = 4; l --> 0; bit_mask >>= 1) + { + if(!(stripe[k].sigma & bit_mask) && !(stripe[k].pi & bit_mask)) + { + if(r >= 0) + { + r--; + } + else + { + k_h = (stripe[k].stripe_l->sigma & bit_mask) + (stripe[k].stripe_r->sigma & bit_mask); + + k_v = ((bit_mask & (stripe[k].sigma >> 1)) + (bit_mask & (stripe[k].sigma << 1))); + + k_d = ((bit_mask & (stripe[k].stripe_l->sigma >> 1)) + (bit_mask & (stripe[k].stripe_l->sigma << 1)) + + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) + (bit_mask & (stripe[k].stripe_r->sigma << 1))); + + if(l == 3) + { + k_v += ((0x01 & stripe[k].stripe_u->sigma) << 3); + k_d += ((0x01 & stripe[k].stripe_u->stripe_l->sigma) + + (0x01 & stripe[k].stripe_u->stripe_r->sigma)) << 3; + } + else if(l == 0) + { + k_v += ((0x08 & stripe[k].stripe_d->sigma) >> 3); + k_d += ((0x08 & stripe[k].stripe_d->stripe_l->sigma) + + (0x08 & stripe[k].stripe_d->stripe_r->sigma)) >> 3; + } + + bit |= (bit_decode(coder->bitcoder, coder->sig2context[(15 * k_h + 5 * k_v + k_d) >> l]) << l); + } + if(bit & bit_mask) + { + xi_h = ((bit_mask & stripe[k].stripe_l->sigma) | ((bit_mask & stripe[k].stripe_l->xi) << 2) | + ((bit_mask & stripe[k].stripe_r->sigma) << 1) | ((bit_mask & stripe[k].stripe_r->xi) << 3)) >> l; + + xi_v = ((bit_mask & (stripe[k].sigma >> 1)) | ((bit_mask & (stripe[k].xi >> 1)) << 2) | + ((bit_mask & (stripe[k].sigma << 1)) << 1) | ((bit_mask & (stripe[k].xi << 1)) << 3)) >> l; + + if(l == 3) + { + xi_v |= ((0x01 & stripe[k].stripe_u->sigma) | ((0x01 & stripe[k].stripe_u->xi) << 2)); + } + else if(l == 0) + { + xi_v |= (((0x08 & stripe[k].stripe_d->sigma) >> 2) | (0x08 & stripe[k].stripe_d->xi)); + } + + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + stripe[k].xi |= ((XI2CONT[(xi_h << 2) | xi_v][1] ^ bit_decode(coder->bitcoder, XI2CONT[(xi_h << 2) | xi_v][0])) << l); + + stripe[k].sigma |= bit_mask; + } + } + } + stripe[k].bit[b] |= bit; + } + } + + if(rest < 4) + { + for(x = 0; x < coder->width; ++x, ++k) + { + bit = 0; + + for(bit_mask = 0x08, l = 4; l --> rest; bit_mask >>= 1) + { + if(!(stripe[k].sigma & bit_mask) && !(stripe[k].pi & bit_mask)) + { + k_h = (stripe[k].stripe_l->sigma & bit_mask) + (stripe[k].stripe_r->sigma & bit_mask); + + k_v = ((bit_mask & (stripe[k].sigma >> 1)) + (bit_mask & (stripe[k].sigma << 1))); + + k_d = ((bit_mask & (stripe[k].stripe_l->sigma >> 1)) + (bit_mask & (stripe[k].stripe_l->sigma << 1)) + + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) + (bit_mask & (stripe[k].stripe_r->sigma << 1))); + + if(l == 3) + { + k_v += ((0x01 & stripe[k].stripe_u->sigma) << 3); + k_d += ((0x01 & stripe[k].stripe_u->stripe_l->sigma) + + (0x01 & stripe[k].stripe_u->stripe_r->sigma)) << 3; + } + + bit |= (bit_decode(coder->bitcoder, coder->sig2context[(15 * k_h + 5 * k_v + k_d) >> l]) << l); + + if(bit & bit_mask) + { + xi_h = ((bit_mask & stripe[k].stripe_l->sigma) | ((bit_mask & stripe[k].stripe_l->xi) << 2) | + ((bit_mask & stripe[k].stripe_r->sigma) << 1) | ((bit_mask & stripe[k].stripe_r->xi) << 3)) >> l; + + xi_v = ((bit_mask & (stripe[k].sigma >> 1)) | ((bit_mask & (stripe[k].xi >> 1)) << 2) | + ((bit_mask & (stripe[k].sigma << 1)) << 1) | ((bit_mask & (stripe[k].xi << 1)) << 3)) >> l; + + if(l == 3) + { + xi_v |= ((0x01 & stripe[k].stripe_u->sigma) | ((0x01 & stripe[k].stripe_u->xi) << 2)); + } + + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + stripe[k].xi |= ((XI2CONT[(xi_h << 2) | xi_v][1] ^ bit_decode(coder->bitcoder, XI2CONT[(xi_h << 2) | xi_v][0])) << l); + + stripe[k].sigma |= bit_mask; + } + } + } + stripe[k].bit[b] |= bit; + } + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 07.03.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uint16 +slope2log(const double lambda) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 exponent, mantissa, raw; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(lambda > 0); + + raw = *(uint64*)λ + + exponent = (uint64)((raw & 0x7FF0000000000000) >> 44) - 0x41F00; + mantissa = (uint64)((raw & 0x000FFFFFFFFFFFFF) >> 44); + raw = (exponent + frac2log[mantissa]) + 0x10000; + + if(raw > 0xFFFF) + { + return 0xFFFF; + } + else if(raw < 2.0) + { + return 2; + } + else + { + return (uint16)raw; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 07.03.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +compute_convex_hull(bwc_encoded_cblk *const encoded_codeblock, double *const mse) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 delta_L; + uint64 *Length; + uint16 *Slope; + uint8 *h; + uint8 hull[MAXIMUM_NO_PASSES] = {0}; + uint8 hlast, i, j; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + double delta_D; + double lambda[MAXIMUM_NO_PASSES + 1] = {0}; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(encoded_codeblock); + + Length = encoded_codeblock->L; + Slope = encoded_codeblock->S; + + h = hull; + hlast = 0; + lambda [0] = 0xFFFFFFFFFFFFFFFF; + + for(i = 0; i < encoded_codeblock->Z; ++i) + { + delta_D = 0; + for(j = hlast; j <= i; ++j) + { + delta_D += mse[j]; + } + delta_L = (hlast > 0) ? (Length[i] - Length[hlast - 1]) : Length[i]; + + if(delta_D > 0) + { + while(delta_D >= (lambda[hlast] * delta_L)) + { + lambda[hlast] = 0; + h--; + hlast = h[0]; + delta_D = 0; + for(j = hlast; j <= i; ++j) + { + delta_D += mse[j]; + } + delta_L = (hlast > 0) ? (Length[i] - Length[hlast - 1]) : Length[i]; + } + + h++; + hlast = i + 1; + h[0] = hlast; + + if(delta_L == 0) + { + if(delta_D < 0) + { + lambda[hlast] = -1; + } + else if(delta_D == 0) + { + lambda[hlast] = 0; + } + else + { + lambda[hlast] = 0xFFFFFFFFFFFFFFFF; + } + } + else + { + lambda[hlast] = delta_D / delta_L; + } + } + else + { + lambda[i + 1] = 0; + } + } + + for(i = 0; i <= encoded_codeblock->Z; ++i) + { + if(lambda[i] < 0) + { + Slope[i] = 1; + } + else if (lambda[i] == 0) + { + if(i == encoded_codeblock->Z) + { + Slope[i] = 1; + } + else + { + Slope[i] = 0; + } + } + else + { + Slope[i] = slope2log(lambda[i]); + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: bwc_encoded_cblk* encode_codeblock(bwc_field *const field, bwc_cblk_access *const access, ! +! -------------- bwc_coder_stripe *const codeblock, ! +! const uint64 width, ! +! const uint64 height, ! +! const uint64 depth, ! +! const uint16 dt) ! +! ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +encode_codeblock(bwc_field *const field, bwc_cblk_access *const access, + bwc_coder_stripe *const codeblock, + const uint64 width, + const uint64 height, + const uint64 depth, + const uint16 dt) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 delta_mse; + int16 k; + uint8 i, j; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + double mse[MAXIMUM_NO_PASSES] = {0}; + double mse_scale; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_subb_ctrl *subb_ctrl; + bwc_subb_inf *subb_inf; + bwc_cblk_ctrl *cblk_ctrl; + bwc_encoded_cblk *encoded_cblk; + bwc_coder coder; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(access); + assert(codeblock); + assert(access->subband->control.highband_flag <= 15); + assert(access->subband->control.Kmax >= + access->codeblock->control.K); + + /*-----------------------*\ + ! DEFINE FUNCTION PTR: ! + \*-----------------------*/ + uint64 (*coding_pass[3])(bwc_coder*, int8) = {significance_propagation_enc_pass, + magnitude_refinement_enc_pass, + cleanup_enc_pass}; + + /*--------------------------------------------------------*\ + ! Save the global, subband and codeblock control, subband ! + ! info and encoded block structure to temporary variables ! + ! to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + subb_ctrl = &access->subband->control; + subb_inf = &access->subband->info; + + cblk_ctrl = &access->codeblock->control; + + encoded_cblk = access->codeblock->encoded_block; + + /*--------------------------------------------------------*\ + ! Check if there are any significant bits present in the ! + ! current codeblock. If not, set the proper slope value ! + ! and return to the function caller. ! + \*--------------------------------------------------------*/ + if(cblk_ctrl->K == 0) + { + encoded_cblk->S[0] = 0xFFFF; + return; + } + + /*--------------------------------------------------------*\ + ! Calculate the buffer increment and initial buffer size ! + ! used to allocate memory that will hold the compressed ! + ! bitstream and increment the buffer if the initial buffer ! + ! size is insufficient. ! + \*--------------------------------------------------------*/ + coder.buff_incr = width * height * depth * dt; + coder.buff_size = coder.buff_incr * PREC_BYTE; + + /*--------------------------------------------------------*\ + ! Save the height and width and calculate the number of ! + ! full stripes and slices for the current codeblockblock. ! + ! These variables are used to walk through the bwc_coder_ ! + ! stripe structure. ! + \*--------------------------------------------------------*/ + coder.height = height; + coder.width = width; + + coder.no_full_stripe = height >> 2; + coder.no_slice = depth * dt; + + /*--------------------------------------------------------*\ + ! Save the index of the first significant bitplane used to ! + ! walk through the sample bitplanes in the bwc_coder_ ! + ! stripe structure. ! + \*--------------------------------------------------------*/ + coder.K = cblk_ctrl->K; + + /*--------------------------------------------------------*\ + ! Save the error resilience and highband flag in the coder ! + ! structure. These flags are used to signal if an error ! + ! resilient bitstream is to be created and which subband ! + ! the current codeblock belongs to. ! + \*--------------------------------------------------------*/ + coder.erres = control->error_resilience; + coder.highband_flag = subb_ctrl->highband_flag; + + /*--------------------------------------------------------*\ + ! Associate the significance-to-context pointer with the ! + ! appropriate lookup table for the current subband. ! + \*--------------------------------------------------------*/ + switch(coder.highband_flag) + { + case 0: + case 2: + case 4: + case 6: + case 8: + case 10: + case 12: + case 14: + { + coder.sig2context = SIG2CONTEXT_L; + break; + } + case 1: + case 5: + case 9: + case 13: + { + coder.sig2context = SIG2CONTEXT_H; + break; + } + case 3: + case 7: + case 11: + case 15: + { + coder.sig2context = SIG2CONTEXT_HH; + break; + } + } + + /*--------------------------------------------------------*\ + ! Associate the data pointer with the bwc_coder_stripe ! + ! codeblock structure and allocate the memory block used ! + ! to hold the compressed bitstream. ! + \*--------------------------------------------------------*/ + coder.data = codeblock; + coder.compressed = calloc(coder.buff_size, sizeof(uchar)); + if(!coder.compressed) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return; + } + + /*--------------------------------------------------------*\ + ! Initialize the entropy encoder used for the current com- ! + ! pression run. ! + \*--------------------------------------------------------*/ + if(initialize_bit_encoder(&coder, CONTEXT_TOTAL)) + { + return; + } + + /*--------------------------------------------------------*\ + ! Calculate the weighting factor for the distrotion cal- ! + ! culation according to the distortion contribution de- ! + ! scribed in JPEG2000 by David S. Taubman and Michael W. ! + ! Marcellin (p. 378). ! + \*--------------------------------------------------------*/ + mse_scale = subb_inf->dwt_gain; + mse_scale *= (subb_ctrl->qt_step_size * subb_ctrl->qt_step_size); + mse_scale *= pow(2, coder.K * 2); + + /*--------------------------------------------------------*\ + ! Scale the weighting factor to account for the integer ! + ! representation of the distortion lookup tables. ! + \*--------------------------------------------------------*/ + mse_scale /= 0x10000; + + for(i = 2, j = 0, k = coder.K; k --> 0; i = 0) + { + for(; i < 3; ++i, ++j) + { + /*--------------------------------------------------------*\ + ! Reset the bit encoder for the next coding pass. ! + \*--------------------------------------------------------*/ + if(bit_encoder_next_run(coder.bitcoder)) + { + return; + } + + delta_mse = coding_pass[i](&coder, k); + mse[j] = delta_mse * mse_scale; + } + /*--------------------------------------------------------*\ + ! Evaluate the number of bytes generated so far by the bit ! + ! encoder and increase the buffer size if necessary. ! + \*--------------------------------------------------------*/ + if(coder.buff_size <= (bit_coder_get_no_bytes(coder.bitcoder) + coder.buff_incr)) + { + coder.buff_size += ((uint64)k >> 1) * coder.buff_incr; + coder.compressed = realloc(coder.compressed, coder.buff_size * sizeof(uchar)); + if(!coder.compressed) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return; + } + + bit_coder_reset_ptr(coder.bitcoder, coder.compressed); + } + /*--------------------------------------------------------*\ + ! If the error resilience flag is set, encode a segmark ! + ! symbol to allow for error detection during decoding. ! + \*--------------------------------------------------------*/ + if(coder.erres) + { + encode_segmark(coder.bitcoder); + } + + /*--------------------------------------------------------*\ + ! Scale the weighting factor to the next bitplane. ! + \*--------------------------------------------------------*/ + mse_scale *= 0.25; + } + /*--------------------------------------------------------*\ + ! Evalute the number of bytes generated by the bit encoder ! + ! and increase the buffer size if necessary. ! + \*--------------------------------------------------------*/ + if(coder.buff_size <= (bit_coder_get_no_bytes(coder.bitcoder) + 16)) + { + coder.buff_size += 16; + coder.compressed = realloc(coder.compressed, coder.buff_size * sizeof(uchar)); + if(!coder.compressed) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return; + } + + bit_coder_reset_ptr(coder.bitcoder, coder.compressed); + } + /*--------------------------------------------------------*\ + ! Flush the remaining bits in the byte buffer to the coder ! + ! output and calculate the minimum truncation lengths. ! + \*--------------------------------------------------------*/ + bit_encoder_termination(coder.bitcoder); + + /*--------------------------------------------------------*\ + ! Save the number of significant bitplanes, insignificant ! + ! leading bitplanes and coding passes in the encoded code- ! + ! block structure. ! + \*--------------------------------------------------------*/ + encoded_cblk->K = coder.K; + encoded_cblk->Kmsbs = subb_ctrl->Kmax - coder.K; + encoded_cblk->Z = j; + + /*--------------------------------------------------------*\ + ! Resize the coder output buffer to its optimal size and ! + ! save the memory handle in the encoded codeblock struc- ! + ! ture. ! + \*--------------------------------------------------------*/ + encoded_cblk->data = realloc(coder.compressed, coder.bitcoder->state->L * sizeof(uchar)); + + /*--------------------------------------------------------*\ + ! Save the lengths of the coding passes in the encoded ! + ! codeblock structure. ! + \*--------------------------------------------------------*/ + bit_coder_get_pass_lengths(coder.bitcoder, encoded_cblk); + + /*--------------------------------------------------------*\ + ! Free the entropy encoder structure. ! + \*--------------------------------------------------------*/ + free_bit_encoder(&coder); + + /*--------------------------------------------------------*\ + ! Calculate the slope values of the distortion/rate convex ! + ! hull. ! + \*--------------------------------------------------------*/ + compute_convex_hull(encoded_cblk, mse); +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: bwc_encoded_cblk* encode_codeblock(bwc_field *const field, bwc_cblk_access *const access, ! +! bwc_coder_stripe *const codeblock, ! +! const uint64 width, ! +! const uint64 height, ! +! const uint64 depth, ! +! const uint16 dt) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! - Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +decode_codeblock(bwc_field *const field, bwc_cblk_access *const access, + bwc_coder_stripe *const codeblock, + const uint64 width, + const uint64 height, + const uint64 depth, + const uint16 dt) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int16 k; + uint8 i, j; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_subb_ctrl *subb_ctrl; + bwc_encoded_cblk *encoded_cblk; + bwc_coder coder; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(access); + assert(codeblock); + assert(access->subband->control.highband_flag <= 15); + assert(access->subband->control.Kmax >= + access->codeblock->control.K); + + /*-----------------------*\ + ! DEFINE FUNCTION PTR: ! + \*-----------------------*/ + void (*decoding_pass[3])(bwc_coder*, int8) = {significance_propagation_dec_pass, + magnitude_refinement_dec_pass, + cleanup_dec_pass}; + + /*--------------------------------------------------------*\ + ! Save the global, subband and codeblock control and info ! + ! structure to temporary variables to make the code more ! + ! readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + subb_ctrl = &access->subband->control; + + encoded_cblk = access->codeblock->encoded_block; + + /*--------------------------------------------------------*\ + ! Save the height and width and calculate the number of ! + ! full stripes and slices for the current codeblockblock. ! + ! These variables are used to walk through the bwc_coder_ ! + ! stripe structure. ! + \*--------------------------------------------------------*/ + coder.height = height; + coder.width = width; + + coder.no_full_stripe = height >> 2; + coder.no_slice = depth * dt; + + /*--------------------------------------------------------*\ + ! Save the index of the first significant bitplane used to ! + ! walk through the sample bitplanes in the bwc_coder_ ! + ! stripe structure. ! + \*--------------------------------------------------------*/ + coder.K = encoded_cblk->K; + + /*--------------------------------------------------------*\ + ! Save the error resilience and highband flag in the coder ! + ! structure. These flags are used to signal if an error ! + ! resilient bitstream is to be created and which subband ! + ! the current codeblock belongs to. ! + \*--------------------------------------------------------*/ + coder.erres = control->error_resilience; + coder.highband_flag = subb_ctrl->highband_flag; + + /*--------------------------------------------------------*\ + ! Associate the significance-to-context pointer with the ! + ! appropriate lookup table for the current subband. ! + \*--------------------------------------------------------*/ + switch(coder.highband_flag) + { + case 0: + case 2: + case 4: + case 6: + case 8: + case 10: + case 12: + case 14: + { + coder.sig2context = SIG2CONTEXT_L; + break; + } + case 1: + case 5: + case 9: + case 13: + { + coder.sig2context = SIG2CONTEXT_H; + break; + } + case 3: + case 7: + case 11: + case 15: + { + coder.sig2context = SIG2CONTEXT_HH; + break; + } + } + + /*--------------------------------------------------------*\ + ! Associate the data pointer with the bwc_coder_stripe ! + ! codeblock structure and allocate the memory block used ! + ! to hold the compressed bitstream. ! + \*--------------------------------------------------------*/ + coder.data = codeblock; + coder.compressed = encoded_cblk->data; + + /*--------------------------------------------------------*\ + ! Initialize the entropy encoder used for the current com- ! + ! pression run. ! + \*--------------------------------------------------------*/ + if(initialize_bit_decoder(&coder, CONTEXT_TOTAL, encoded_cblk->L[encoded_cblk->Z - 1])) + { + return; + } + + for(i = 2, j = encoded_cblk->Z, k = coder.K; k --> 0; i = 0) + { + for(; i < 3; ++i, --j) + { + if(j == 0) + { + goto break_out; + } + decoding_pass[i](&coder, k); + } + + if((coder.erres) && (((bit_decode(coder.bitcoder, CONTEXT_UNI) << 3) | + (bit_decode(coder.bitcoder, CONTEXT_UNI) << 2) | + (bit_decode(coder.bitcoder, CONTEXT_UNI) << 1) | + bit_decode(coder.bitcoder, CONTEXT_UNI)) != 0x0A)) + { + goto break_out; + } + } + + break_out: + + /*--------------------------------------------------------*\ + ! Save the last bitplane and coding pass in the data struc-! + ! ture for proper reconstruction. ! + \*--------------------------------------------------------*/ + coder.data->bitplane = (k > 0) ? k : 0; + coder.data->codingpass = i; + + /*--------------------------------------------------------*\ + ! Free the entropy encoder structure. ! + \*--------------------------------------------------------*/ + free_bit_encoder(&coder); +} + +/************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +t1_encode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const parameter) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 c; + uint64 cbSizeX, cbSizeY, cbSizeZ; + uint64 width, height, depth; + int64 buff_size; + int64 j; + uint16 cbSizeTS; + uint16 slope_max, slope_min; + int16 i, z; + uint8 nThreads; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_codeblock *codeblock; + bwc_cblk_inf *cblk_info; + bwc_coder_stripe *working_buffer; + bwc_coder_stripe **memory; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(tile); + assert(parameter); + + /*--------------------------------------------------------*\ + ! Save the global control structure to a temporary varia- ! + ! ble to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Save the minimum and maximum slope values for the cur- ! + ! rent parameter tile to temporary variables to make the ! + ! code more readable. ! + \*--------------------------------------------------------*/ + slope_max = tile->control.slope_max; + slope_min = tile->control.slope_min; + + /*--------------------------------------------------------*\ + ! Evaluate the width, height and depth of the current ! + ! parameter. ! + \*--------------------------------------------------------*/ + width = parameter->info.X1 - parameter->info.X0; + height = parameter->info.Y1 - parameter->info.Y0; + depth = parameter->info.Z1 - parameter->info.Z0; + + /*--------------------------------------------------------*\ + ! Evaluate the number of threads used for the current com- ! + ! pression run. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + nThreads = control->nThreads; + #else + nThreads = 1; + #endif + + /*--------------------------------------------------------*\ + ! Calculate the size of the buffer that holds the wavelet ! + ! coefficients for the entropy encoding stage. The size of ! + ! the buffer is divided by 4 since the Structure is organ- ! + ! ized in a (4-sample per) stripe pattern. Additionally, ! + ! the size is increased by two to account for boundary ! + ! handling during the entropy encoding stage. ! + \*--------------------------------------------------------*/ + buff_size = (uint64)(1 << (control->cbX + (control->cbY >= 2 ? control->cbY - 2 : 0) + + control->cbZ + control->cbTS)) + 2; + + /*--------------------------------------------------------*\ + ! Allocate the pointer array which holds the memory addres-! + ! es for the working buffers that are used by the OpenMP ! + ! threads during a parallel run. For a serial run the ! + ! pointer array has the size 1. ! + \*--------------------------------------------------------*/ + memory = calloc(nThreads, sizeof(bwc_coder_stripe*)); + if(!memory) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Allocate the working buffers that are used by the OpenMP ! + ! threads during a parallel run. For a serial run only one ! + ! working buffer is allocated. ! + \*--------------------------------------------------------*/ + for(i = 0; i < nThreads; ++i) + { + memory[i] = calloc(buff_size, sizeof(bwc_coder_stripe)); + if(!memory[i]) + { + // memory allocation error + fprintf(stderr, MEMERROR); + for(; i --> 0;) + { + for(j = buff_size - 1; j --> 0;) + { + free(memory[i][j].bit); + free(memory[i][j].sample); + } + free(memory[i]); + } + free(memory); + return 1; + } + /*--------------------------------------------------------*\ + ! The left and right neighbours for the dummy stripe, re- ! + ! presenting the upper and lower boundary of the code- ! + ! block, are set to the dummy stripe used to describe its ! + ! vertical boundaries to properly uncouple the evaluation ! + ! of the context lables from the neighbouring codeblocks. ! + \*--------------------------------------------------------*/ + memory[i][1].stripe_r = &memory[i][0]; + memory[i][1].stripe_l = &memory[i][0]; + + /*--------------------------------------------------------*\ + ! Allocate the sample and bit arrays used to hold the mag- ! + ! nitude of a wavelet coefficient and its bitplane repre- ! + ! sentation. ! + \*--------------------------------------------------------*/ + for(j = 0; j < buff_size; ++j) + { + memory[i][j].bit = calloc(PREC_BIT, sizeof(uint8)); + memory[i][j].sample = calloc(4, sizeof(uint64)); + if(!memory[i][j].sample || !memory[i][j].bit) + { + // memory allocation error + fprintf(stderr, MEMERROR); + for(; i >= 0; --i) + { + for(; j >= 0; --j) + { + free(memory[i][j].bit); + free(memory[i][j].sample); + } + j = buff_size; + free(memory[i]); + } + free(memory); + return 1; + } + } + } + + #if defined(_OPENMP) + #pragma omp parallel private(working_buffer, codeblock, cblk_info, cbSizeX, cbSizeY, cbSizeZ, cbSizeTS) reduction(max:slope_max) reduction(min:slope_min) + #endif + { + /*--------------------------------------------------------*\ + ! Associate the working buffer pointer to the allocated ! + ! memory block. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + working_buffer = &memory[omp_get_thread_num()][2]; + #else + working_buffer = &memory[0][2]; + #endif + + /*--------------------------------------------------------*\ + ! Loop through and encode all codeblocks for the current ! + ! parameter. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp for + #endif + for(c = 0; c < parameter->control.number_of_codeblocks; ++c) + { + /*--------------------------------------------------------*\ + ! Save the codeblock and codeblock info structure to tempo-! + ! rary variables to make the code more readable. ! + \*--------------------------------------------------------*/ + codeblock = parameter->access[c].codeblock; + cblk_info = &codeblock->info; + + /*--------------------------------------------------------*\ + ! Evaluate the width, height, depth and dt for the current ! + ! codeblock. ! + \*--------------------------------------------------------*/ + cbSizeX = cblk_info->X1 - cblk_info->X0; + cbSizeY = cblk_info->Y1 - cblk_info->Y0; + cbSizeZ = cblk_info->Z1 - cblk_info->Z0; + cbSizeTS = cblk_info->TS1 - cblk_info->TS0; + + /*--------------------------------------------------------*\ + ! Copy the wavelet coefficients for the current codeblock ! + ! from the data to the working buffer memory block. The ! + ! working buffer stores the codeblock in stripes of 4 co- ! + ! efficients. Additionally, a bitplane representation of ! + ! each coefficient is evaluated for easy access during the ! + ! entropy encoding stage. ! + \*--------------------------------------------------------*/ + cblkcopy_forward(working_buffer, parameter->data, + ¶meter->access[c], width, + height, depth); + + /*--------------------------------------------------------*\ + ! Encode the wavelet coefficients for the current code- ! + ! block and save the compressed bitstream (data), number ! + ! of coding passes (Z), number of encoded bitplanes (K), ! + ! number of non-significant, leading bitplanes (Kmsbs), ! + ! truncation points (L) and possible slope values (S) in ! + ! the bwc_encoded_cblk structure. ! + \*--------------------------------------------------------*/ + encode_codeblock(field, ¶meter->access[c], working_buffer, + cbSizeX, cbSizeY, + cbSizeZ, cbSizeTS); + + /*--------------------------------------------------------*\ + ! Check if a compressed bitstream has been created. ! + \*--------------------------------------------------------*/ + if(codeblock->encoded_block->data) + { + /*--------------------------------------------------------*\ + ! Walk through all coding passes, ... ! + \*--------------------------------------------------------*/ + for(z = 0; z <= codeblock->encoded_block->Z; ++z) + { + /*--------------------------------------------------------*\ + ! ...check if a viable slope value has been created... ! + \*--------------------------------------------------------*/ + if(codeblock->encoded_block->S[z]) + { + /*--------------------------------------------------------*\ + ! ...and update the minimum and maximum slope values for ! + ! the current parameter tile. ! + \*--------------------------------------------------------*/ + slope_max = MAX(slope_max, codeblock->encoded_block->S[z]); + slope_min = MIN(slope_min, codeblock->encoded_block->S[z]); + } + } + } + + /*--------------------------------------------------------*\ + ! Reset the working buffer for the next entropy encoding ! + ! pass. ! + \*--------------------------------------------------------*/ + cblkreset_fwd(working_buffer, cbSizeX * ceil((double)cbSizeY/4) * cbSizeZ * cbSizeTS); + } + } + + /*--------------------------------------------------------*\ + ! Update the minimum and maximum slope values for the cur- ! + ! rent parameter tile. ! + \*--------------------------------------------------------*/ + tile->control.slope_max = slope_max; + tile->control.slope_min = slope_min; + + /*--------------------------------------------------------*\ + ! Deallocate the working buffer pointer array and memory ! + ! blocks. ! + \*--------------------------------------------------------*/ + for(i = 0; i < nThreads; ++i) + { + for(j = 0; j < buff_size; ++j) + { + free(memory[i][j].bit); + free(memory[i][j].sample); + } + free(memory[i]); + } + free(memory); + + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void *test(void) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +t1_decode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const parameter) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 c; + uint64 cbSizeX, cbSizeY, cbSizeZ; + uint64 width, height, depth; + int64 buff_size; + int64 j; + uint16 cbSizeTS; + int16 i; + uint8 nThreads; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_codeblock *codeblock; + bwc_cblk_inf *cblk_info; + bwc_subb_ctrl *subb_ctrl; + bwc_coder_stripe *working_buffer; + bwc_coder_stripe **memory; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(tile); + assert(parameter); + + /*--------------------------------------------------------*\ + ! Save the global control structure to a temporary varia- ! + ! ble to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Evaluate the width, height and depth of the current ! + ! parameter. ! + \*--------------------------------------------------------*/ + width = parameter->info.X1 - parameter->info.X0; + height = parameter->info.Y1 - parameter->info.Y0; + depth = parameter->info.Z1 - parameter->info.Z0; + + /*--------------------------------------------------------*\ + ! Evaluate the number of threads used for the current de- ! + ! compression run. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + nThreads = control->nThreads; + #else + nThreads = 1; + #endif + + /*--------------------------------------------------------*\ + ! Calculate the size of the buffer that holds the decoded ! + ! wavelet coefficients. The size of the buffer is divided ! + ! by 4 since the Structure is organized in a (4-sample per)! + ! stripe pattern. Additionally, the size is increased by ! + ! two to account for boundary handling during the entropy ! + ! encoding stage. ! + \*--------------------------------------------------------*/ + buff_size = (uint64)(1 << (control->cbX + (control->cbY >= 2 ? control->cbY - 2 : 0) + + control->cbZ + control->cbTS)) + 2; + + /*--------------------------------------------------------*\ + ! Allocate the pointer array which holds the memory addres-! + ! es for the working buffers that are used by the OpenMP ! + ! threads during a parallel run. For a serial run the ! + ! pointer array has the size 1. ! + \*--------------------------------------------------------*/ + memory = calloc(nThreads, sizeof(bwc_coder_stripe*)); + if(!memory) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Allocate the working buffers that are used by the OpenMP ! + ! threads during a parallel run. For a serial run only one ! + ! working buffer is allocated. ! + \*--------------------------------------------------------*/ + for(i = 0; i < nThreads; ++i) + { + memory[i] = calloc(buff_size, sizeof(bwc_coder_stripe)); + if(!memory[i]) + { + // memory allocation error + fprintf(stderr, MEMERROR); + for(; i --> 0;) + { + for(j = buff_size - 1; j --> 0;) + { + free(memory[i][j].bit); + free(memory[i][j].sample); + } + free(memory[i]); + } + free(memory); + return 1; + } + /*--------------------------------------------------------*\ + ! The left and right neighbours for the dummy stripe, re- ! + ! presenting the upper and lower boundary of the code- ! + ! block, are set to the dummy stripe used to describe its ! + ! vertical boundaries to properly uncouple the evaluation ! + ! of the context lables from the neighbouring codeblocks. ! + \*--------------------------------------------------------*/ + memory[i][1].stripe_r = &memory[i][0]; + memory[i][1].stripe_l = &memory[i][0]; + + /*--------------------------------------------------------*\ + ! Allocate the sample and bit arrays used to hold the mag- ! + ! nitude of a wavelet coefficient and its bitplane repre- ! + ! sentation. ! + \*--------------------------------------------------------*/ + for(j = 0; j < buff_size; ++j) + { + memory[i][j].bit = calloc(PREC_BIT, sizeof(uint8)); + memory[i][j].sample = calloc(4, sizeof(uint64)); + if(!memory[i][j].sample || !memory[i][j].bit) + { + // memory allocation error + fprintf(stderr, MEMERROR); + for(; i >= 0; --i) + { + for(; j >= 0; --j) + { + free(memory[i][j].bit); + free(memory[i][j].sample); + } + j = buff_size; + free(memory[i]); + } + free(memory); + return 1; + } + } + } + + #if defined(_OPENMP) + #pragma omp parallel private(working_buffer, codeblock, cblk_info, subb_ctrl,\ + cbSizeX, cbSizeY, cbSizeZ, cbSizeTS) + #endif + { + /*--------------------------------------------------------*\ + ! Associate the working buffer pointer to the allocated ! + ! memory block. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + working_buffer = &memory[omp_get_thread_num()][2]; + #else + working_buffer = &memory[0][2]; + #endif + + /*--------------------------------------------------------*\ + ! Loop through and encode all codeblocks for the current ! + ! parameter. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp for + #endif + for(c = 0; c < parameter->control.number_of_codeblocks; ++c) + { + /*--------------------------------------------------------*\ + ! Save the codeblock, subband info and codeblock info and ! + ! control structure to temporary variables to make the ! + ! code more readable. ! + \*--------------------------------------------------------*/ + subb_ctrl = ¶meter->access[c].subband->control; + codeblock = parameter->access[c].codeblock; + cblk_info = &codeblock->info; + + /*--------------------------------------------------------*\ + ! Evaluate the width, height, depth and dt for the current ! + ! codeblock. ! + \*--------------------------------------------------------*/ + cbSizeX = cblk_info->X1 - cblk_info->X0; + cbSizeY = cblk_info->Y1 - cblk_info->Y0; + cbSizeZ = cblk_info->Z1 - cblk_info->Z0; + cbSizeTS = cblk_info->TS1 - cblk_info->TS0; + + /*--------------------------------------------------------*\ + ! Evaluate the index of the first significant bitplane for ! + ! the current codeblock. ! + \*--------------------------------------------------------*/ + codeblock->encoded_block->K = subb_ctrl->Kmax - codeblock->encoded_block->Kmsbs; + + /*--------------------------------------------------------*\ + ! Reset the working buffer for the next entropy encoding ! + ! pass. ! + \*--------------------------------------------------------*/ + cblkreset_inv(working_buffer, cbSizeX, cbSizeY, + cbSizeZ, cbSizeTS); + + if(codeblock->encoded_block->Z > 0) + { + decode_codeblock(field, ¶meter->access[c], working_buffer, + cbSizeX, cbSizeY, + cbSizeZ, cbSizeTS); + } + + /*--------------------------------------------------------*\ + ! Copy the wavelet coefficients for the current codeblock ! + ! from the working buffer to the data memory block. ! + \*--------------------------------------------------------*/ + cblkcopy_inverse(working_buffer, parameter->data, + ¶meter->access[c], width, + height, depth); + } + } + + /*--------------------------------------------------------*\ + ! Deallocate the working buffer pointer array and memory ! + ! blocks. ! + \*--------------------------------------------------------*/ + for(i = 0; i < nThreads; ++i) + { + for(j = 0; j < buff_size; ++j) + { + free(memory[i][j].bit); + free(memory[i][j].sample); + } + free(memory[i]); + } + free(memory); + + return 0; +} diff --git a/src/library/tier2.c b/src/library/tier2.c new file mode 100755 index 0000000..048dad1 --- /dev/null +++ b/src/library/tier2.c @@ -0,0 +1,1704 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| FILE NAME: t2.c || +|| || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| FILE REFERENCES: || +|| ---------------- || +|| || +|| Name I/O Description || +|| ---- --- ----------- || +|| none - - || +|| || +|| || +|| PRIVATE FUNCTIONS: || +|| ------------------ || +|| - encode_length || +|| - decode_length || +|| - create_packet || +|| - create_packets || +|| - create_quality_layer || +|| - create_quality_layers || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| - t2_encode || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| - Patrick Vogler B87D120 V 0.1.0 source file created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ + +/************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\************************************************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#include "codestream.h" +#include "bitstream.h" +#include "constants.h" +#include "macros.h" +#include "types.h" +#include "tagtree.h" +#include "tier2.h" + +/************************************************************************************************************\ +|| _ _ ____ ____ ____ ____ ____ || +|| |\/| |__| | |__/ | | [__ || +|| | | | | |___ | \ |__| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! DESCRIPTION: ! +! ------------ ! +! These macros define a variable length encoder and decoder for the delta z (new coding ! +! passes) information. ! +! ! +! Macros: ! +! ------- ! +! Macro Description ! +! ----- ----------- ! +! encode_delta_z - Encoding algorithm used to store the number of new ! +! coding passes in a packet header. ! +! ! +! dencode_delta_z - Decoding algorithm used to extract the number of new ! +! coding passes form a packet header. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 13.05.2019 Patrick Vogler B87D120 V 0.1.0 Macros created ! +\*----------------------------------------------------------------------------------------------------------*/ +#define encode_delta_z(stream, delta_z) \ +{ \ + if(delta_z == 1) \ + { \ + bwc_emit_bit(stream, 0); \ + } \ + else if(delta_z == 2) \ + { \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 0); \ + } \ + else if(delta_z < 6) \ + { \ + delta_z -= 3; \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 0x02 & delta_z); \ + bwc_emit_bit(stream, 0x01 & delta_z); \ + } \ + else if(delta_z < 37) \ + { \ + delta_z -= 6; \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 0x10 & delta_z); \ + bwc_emit_bit(stream, 0x08 & delta_z); \ + bwc_emit_bit(stream, 0x04 & delta_z); \ + bwc_emit_bit(stream, 0x02 & delta_z); \ + bwc_emit_bit(stream, 0x01 & delta_z); \ + } \ + else if(delta_z < 293) \ + { \ + delta_z -= 37; \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 1); \ + bwc_emit_bit(stream, 0x080 & delta_z); \ + bwc_emit_bit(stream, 0x040 & delta_z); \ + bwc_emit_bit(stream, 0x020 & delta_z); \ + bwc_emit_bit(stream, 0x010 & delta_z); \ + bwc_emit_bit(stream, 0x008 & delta_z); \ + bwc_emit_bit(stream, 0x004 & delta_z); \ + bwc_emit_bit(stream, 0x002 & delta_z); \ + bwc_emit_bit(stream, 0x001 & delta_z); \ + } \ +} + +#define decode_delta_z(stream, delta_z) \ +{ \ + if(!bwc_get_bit(stream)) \ + { \ + delta_z = 1; \ + } \ + else if(!bwc_get_bit(stream)) \ + { \ + delta_z = 2; \ + } \ + else \ + { \ + delta_z = (bwc_get_bit(stream) << 1) | \ + bwc_get_bit(stream); \ + \ + if(delta_z < 3) \ + { \ + delta_z += 3; \ + } \ + else \ + { \ + delta_z = (bwc_get_bit(stream) << 4) | \ + (bwc_get_bit(stream) << 3) | \ + (bwc_get_bit(stream) << 2) | \ + (bwc_get_bit(stream) << 1) | \ + bwc_get_bit(stream); \ + \ + if(delta_z < 31) \ + { \ + delta_z += 6; \ + } \ + else \ + { \ + delta_z = (bwc_get_bit(stream) << 7) | \ + (bwc_get_bit(stream) << 6) | \ + (bwc_get_bit(stream) << 5) | \ + (bwc_get_bit(stream) << 4) | \ + (bwc_get_bit(stream) << 3) | \ + (bwc_get_bit(stream) << 2) | \ + (bwc_get_bit(stream) << 1) | \ + bwc_get_bit(stream); \ + \ + delta_z += 37; \ + } \ + } \ + } \ +} + +/************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void encode_length(bwc_stream *const header, bwc_codeblock *const codeblock, ! +! -------------- int8 const quality_layer, ! +! uchar const estimate) ! +! ! +! ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 29.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +encode_length(bwc_stream *const header, bwc_codeblock *const codeblock, + int8 const quality_layer, + uchar const estimate) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint32 L; + int32 L_bits; + uint16 beta, max_beta; + uint16 cp_bits; + int16 *cp_contr; + int16 z_curr, z_prev; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_cblk_ctrl *cblk_ctrl; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(codeblock); + assert(header); + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + cblk_ctrl = &codeblock->control; + cp_contr = cblk_ctrl->cp_contr; + + z_curr = cp_contr[quality_layer ] - 1; + z_prev = cp_contr[quality_layer - 1] - 1; + + beta = (!estimate) ? cblk_ctrl->beta : cblk_ctrl->beta_est; + max_beta = beta; + + L = codeblock->encoded_block->L[z_curr] - + ((z_prev >= 0) ? codeblock->encoded_block->L[z_prev] : 0); + + cp_bits = (uint16)log2(z_curr - z_prev); + L_bits = (uint16)log2(L) + 1 - cp_bits; + + max_beta = (max_beta < L_bits) ? L_bits : max_beta; + + while(beta < max_beta) + { + bwc_emit_bit(header, 1); + beta++; + } + + bwc_emit_bit(header, 0); + + L_bits = 1 << (beta + cp_bits - 1); + + while(L_bits > 0) + { + bwc_emit_bit(header, L & L_bits); + L_bits >>= 1; + } + + if(estimate == 0) + { + cblk_ctrl->beta = beta; + cblk_ctrl->beta_est = beta; + } + else if(estimate == 1) + { + cblk_ctrl->beta_est = beta; + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void create_quality_layers(bwc_field *const field, bwc_tile *const tile) ! +! -------------- ! +! ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 29.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +decode_length(bwc_stream *const header, bwc_codeblock *const codeblock, int8 const quality_layer) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint32 i; + uint16 L_bits; + int16 *cp_contr; + int16 z_curr, z_prev; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_cblk_ctrl *cblk_ctrl; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(codeblock); + assert(header); + + cblk_ctrl = &codeblock->control; + cp_contr = cblk_ctrl->cp_contr; + + while(bwc_get_bit(header)) + { + cblk_ctrl->beta++; + } + + z_curr = cp_contr[quality_layer ] - 1; + z_prev = cp_contr[quality_layer - 1] - 1; + + L_bits = cblk_ctrl->beta + (uint16)log2(z_curr - z_prev); + + for(i = 0; L_bits > 0; --L_bits) + { + i <<= 1; + i |= bwc_get_bit(header); + } + + codeblock->encoded_block->L[z_curr] = ((z_prev >= 0) ? codeblock->encoded_block->L[z_prev] : 0) + i; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: int64 create_packet(bwc_field *const field, bwc_tile *const tile, ! +! -------------- bwc_resolution *const resolution, ! +! uint32 const prec_idx, ! +! int8 const q_layer, ! +! uchar const est) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to assemble a codestream packet for a given precinct (prec_idx) ! +! and quality layer (q_layer). In order to facilitate a fast quality layer creation, ! +! the est flag can be used to instruct the function to merely estimate the packet head- ! +! er size and circumvent the packet body creation. If est > 1 only the header size is ! +! evaluated, while for est = 1 the packet body size is calculated as well. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! tile bwc_tile* - Structure defining a bwc tile. ! +! ! +! resolution bwc_resolution* - Structure defining a bwc resolution ! +! level. ! +! ! +! prec_idx unsigned int(32 bit) - Index of the current precinct. ! +! ! +! q_layer signed int(16 bit) - Index of the current quality layer. ! +! ! +! est unsigned char - Flag used to instruct the function on ! +! wether a header byte size estimation or ! +! a final packet assembly is required. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! integer(16 bit) - Returns the packet header size if successful or -1 if an ! +! error occurred. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 29.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static int32 +create_packet(bwc_field *const field, bwc_tile *const tile, + bwc_resolution *const resolution, + uint32 const prec_idx, + int16 const q_layer, + uchar const est) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint32 size, start, end; + uint32 k; + uint16 cb; + int16 *cp_contr; + int16 delta_z; + int8 m; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_packet *packet; + bwc_precinct *precinct; + bwc_codeblock *codeblock; + bwc_stream *header; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(tile); + assert(resolution); + + /*--------------------------------------------------------*\ + ! Save the current packet structure to a temporary varia- ! + ! ble to make the code more readable. ! + \*--------------------------------------------------------*/ + packet = &resolution->packet[q_layer * resolution->control.number_of_precincts + prec_idx]; + + /*--------------------------------------------------------*\ + ! Check if the current packet has any codeblock contribu- ! + ! tion. ! + \*--------------------------------------------------------*/ + if(packet->e) + { + /*--------------------------------------------------------*\ + ! Initialize the stream that is used to assemble the pack- ! + ! et header. ! + \*--------------------------------------------------------*/ + header = bwc_init_stream(NULL, PACKET_HEADER_SIZE, 'c'); + if(!header) + { + // memory allocation error + return -1; + } + + /*--------------------------------------------------------*\ + ! If the function caller does not specify a packet size es-! + ! timation, allocate the packet body packed stream that is ! + ! used to hold the codeblock contributions to the current ! + ! qualitylayer. ! + \*--------------------------------------------------------*/ + if(!est) + { + packet->body.access = + packet->body.memory = calloc(packet->body.size, sizeof(bwc_packed_stream)); + if(!packet->body.memory) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return -1; + } + } + + /*--------------------------------------------------------*\ + ! Emit the contribution bit to the packet header that sig- ! + ! nals a non-empty packet body. ! + \*--------------------------------------------------------*/ + bwc_emit_bit(header, 1); + + /*--------------------------------------------------------*\ + ! Iterate over all codeblocks in all subbands to assemble ! + ! the packet header and, if no estimation has been spec- ! + ! ified, body. ! + \*--------------------------------------------------------*/ + for(m = 0; m < resolution->control.number_of_subbands; ++m) + { + /*--------------------------------------------------------*\ + ! Save the precinct structure to a temporary variable to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + precinct = &resolution->subband[m].precinct[prec_idx]; + + for(cb = 0; cb < precinct->control.number_of_codeblocks; ++cb) + { + /*--------------------------------------------------------*\ + ! Save the codeblock and coding pass contribution struc- ! + ! tures to temporary variables to make the code more ! + ! readable. ! + \*--------------------------------------------------------*/ + codeblock = &precinct->codeblock[cb]; + cp_contr = codeblock->control.cp_contr; + + /*--------------------------------------------------------*\ + ! Evaluate the new coding passes added to the packet body ! + ! for the current quality layer. ! + \*--------------------------------------------------------*/ + delta_z = cp_contr[q_layer] - cp_contr[q_layer - 1]; + + /*--------------------------------------------------------*\ + ! Evaluate if the current codeblock already contributed to ! + ! a packet. ! + \*--------------------------------------------------------*/ + if(cp_contr[q_layer - 1] == 0) + { + /*--------------------------------------------------------*\ + ! If no contribution has yet been made, encode the inclu- ! + ! sion tagtree for the current codeblock and... ! + \*--------------------------------------------------------*/ + encode_tagtree(precinct->control.tag_inclusion, header, q_layer + 1, cb, est); + + /*--------------------------------------------------------*\ + ! If the codeblock contributes to the current packet, en- ! + ! code the tagtree for the non-significant most signifi- ! + ! cant bit planes. ! + \*--------------------------------------------------------*/ + if(cp_contr[q_layer]) + { + for(k = 1; k <= codeblock->encoded_block->Kmsbs + 1u; ++k) + { + encode_tagtree(precinct->control.tag_msbs, header, k, cb, est); + } + } + } + else + { + /*--------------------------------------------------------*\ + ! If a contribution has already been made, transmit a flag ! + ! to signal if new coding passes are to be contributed. ! + \*--------------------------------------------------------*/ + bwc_emit_bit(header, delta_z); + } + + /*--------------------------------------------------------*\ + ! Check if new coding passes contributions are available. ! + \*--------------------------------------------------------*/ + if(delta_z) + { + /*--------------------------------------------------------*\ + ! If new coding passes are available, encode delta_z and ! + ! the corresponding coding pass lengths in the packet ! + ! header. ! + \*--------------------------------------------------------*/ + encode_delta_z(header, delta_z); + encode_length(header, codeblock, q_layer, est); + + /*--------------------------------------------------------*\ + ! If the final quality layer (est = 1) or packet (est = 0) ! + ! are assembled, evaluate the start and end points as well ! + ! as the size of the contribution in the encoded block ! + ! memory block and... ! + \*--------------------------------------------------------*/ + if(est <= 1) + { + start = (cp_contr[q_layer - 1] == 0) ? 0 : codeblock->encoded_block->L[cp_contr[q_layer - 1] - 1]; + end = (cp_contr[q_layer] == 0) ? 0 : codeblock->encoded_block->L[cp_contr[q_layer] - 1]; + size = end - start; + + /*--------------------------------------------------------*\ + ! ...add up the packet body size for the final quality ! + ! layer assembly or... ! + \*--------------------------------------------------------*/ + if(est == 1) + { + packet->body.size += size; + } + /*--------------------------------------------------------*\ + ! ...copy the contribution to the packet body for the fi- ! + ! nal packet assembly. ! + \*--------------------------------------------------------*/ + else + { + memcpy(packet->body.access, codeblock->encoded_block->data + start, size); + packet->body.access += size; + packet->body.position += size; + } + } + } + } + } + + /*--------------------------------------------------------*\ + ! Flush the remaining bits from the buffer to the header ! + ! stream. ! + \*--------------------------------------------------------*/ + flush_stream(header); + + /*--------------------------------------------------------*\ + ! If a packet header size estimation has been performed ! + ! (est > 0), reset the non-empty packet flag, free the ! + ! header stream and return the estimated number of header ! + ! bytes to the function caller. ! + \*--------------------------------------------------------*/ + if(est) + { + if(est == 2) + { + packet->e = 0; + } + + k = header->L; + bwc_terminate_stream(header, NULL); + return k; + } + /*--------------------------------------------------------*\ + ! If the final packet has been assembled, terminate the ! + ! header stream, evaluate the overall packet size and re- ! + ! turn the total number of header bytes to the function ! + ! caller. ! + \*--------------------------------------------------------*/ + else + { + if(bwc_terminate_stream(header, &packet->header)) + { + // memory allocation error + return -1; + } + + packet->size = packet->body.size + packet->header.size; + + return packet->header.size; + } + } + else + { + /*--------------------------------------------------------*\ + ! If the packet has no codeblock contributions, reset the ! + ! non-empty packet flag and return a header size of 1 for ! + ! a packet header size estimation or... ! + \*--------------------------------------------------------*/ + if(est) + { + if(est == 2) + { + packet->e = 0; + } + + return 1; + } + /*--------------------------------------------------------*\ + ! ... set the overall packet and header size to 1 and re- ! + ! turn the value to the function caller. ! + \*--------------------------------------------------------*/ + else + { + packet->size = 1; + packet->header.size = 1; + + packet->header.access = + packet->header.memory = calloc(1, sizeof(uchar)); + if(packet->header.memory == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return -1; + } + + return packet->header.size; + } + } +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar create_packets(bwc_field *const field, bwc_tile *const tile) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function iterates overall quality layers for every precinct in all resolution ! +! levels to create the codestream packets for all tile parameters. If an error occurres ! +! during packet creation the function returns to the function caller with an error flag. ! +! If packet creation for all quality layers belonging to a specific precinct is success- ! +! ful, the function iterates over all codeblocks that are a part of the current precinct, ! +! to free all encoded memory blocks and reset the encoded block structure for the next ! +! compression run. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! tile bwc_tile* - Structure defining a bwc tile. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 29.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uchar +create_packets(bwc_field *const field, bwc_tile *const tile) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 cb, p; + uint16 j, r; + uint8 l, m; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + bwc_parameter *parameter; + bwc_resolution *resolution; + bwc_codeblock *codeblock; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(tile); + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = field->info; + + /*--------------------------------------------------------*\ + ! Iterate overall quality layers for every precinct in all ! + ! resolution levels to create the codestream packets for ! + ! all tile parameters. ! + \*--------------------------------------------------------*/ + for(j = 0; j < info->nPar; ++j) + { + /*--------------------------------------------------------*\ + ! Save the parameter structure to a temporary variable to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + parameter = &tile->parameter[j]; + + for(r = 0; r < control->nDecomp + 1; ++r) + { + /*--------------------------------------------------------*\ + ! Save the resolution structure to a temporary variable to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + resolution = ¶meter->resolution[r]; + + for(p = 0; p < resolution->control.number_of_precincts; ++p) + { + for(l = 0; l < control->nLayers; ++l) + { + if(create_packet(field, tile, resolution, p, l, 0) < 0) + { + // memory allocation error + return 1; + } + } + + /*--------------------------------------------------------*\ + ! If packet creation for all quality layers belonging to ! + ! the current precinct is successful, iterate over all ! + ! codeblocks that are a part of the current precinct and ! + ! reset the encoded block structure for another compres- ! + ! sion run. ! + \*--------------------------------------------------------*/ + for(m = 0; m < resolution->control.number_of_subbands; ++m) + { + for(cb = 0; cb < resolution->subband[m].precinct[p].control.number_of_codeblocks; ++cb) + { + /*--------------------------------------------------------*\ + ! Save the codeblock structure and to a temporary variable ! + ! to make the code more readable. ! + \*--------------------------------------------------------*/ + codeblock = &resolution->subband[m].precinct[p].codeblock[cb]; + + /*--------------------------------------------------------*\ + ! Free the encoded block memory block that holds the com- ! + ! pressed codeblock bitstream. ! + \*--------------------------------------------------------*/ + free(codeblock->encoded_block->data); + + /*--------------------------------------------------------*\ + ! Reset the encoded block and coding pass contribution ! + ! structure for the next compression run. ! + \*--------------------------------------------------------*/ + memset(codeblock->encoded_block, 0, sizeof(bwc_encoded_cblk)); + memset(codeblock->control.cp_contr, 0, sizeof(int16) * control->nLayers); + } + } + } + } + } + return 0; +} + + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: int64 create_quality_layer(bwc_field *const field, bwc_tile *const tile, ! +! -------------- uint16 const threshold, ! +! int16 const q_layer, ! +! uchar const est) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function iterates over all codeblocks for every precinct in all resolution levels ! +! to assemble the quality layers for all tile parameters. If an error occurres during ! +! packet creation the function returns to the function caller with an error flag. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! tile bwc_tile* - Structure defining a bwc tile. ! +! ! +! threshold unsigned int(16 bit) - Index of the current quality layer. ! +! ! +! q_layer signed int(16 bit) - Index of the current quality layer. ! +! ! +! est unsigned char - Flag used to instruct the function on ! +! wether a quality layer size estimation ! +! or final assembly is required. ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! integer(16 bit) - Returns the quality layer size if successful or -1 if an ! +! error occurred. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 29.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static int64 +create_quality_layer(bwc_field *const field, bwc_tile *const tile, + uint16 const threshold, + int16 const q_layer, + uchar const est) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 cb, nPrec, p; + int64 estimated_ql_size, estimated_ph_size; + uint16 j, r; + int16 *cp_contr; + int16 z; + uint8 l, m; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + bwc_parameter *parameter; + bwc_resolution *resolution; + bwc_subband *subband; + bwc_codeblock *codeblock; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(tile); + + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = field->info; + + for(j = 0, estimated_ql_size = 0; j < info->nPar; ++j) + { + /*--------------------------------------------------------*\ + ! Save the parameter structure to a temporary variable to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + parameter = &tile->parameter[j]; + + for(r = 0; r < control->nDecomp + 1; ++r) + { + /*--------------------------------------------------------*\ + ! Save the resolution structure to a temporary variable to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + resolution = ¶meter->resolution[r]; + nPrec = resolution->control.number_of_precincts; + + for(m = 0; m < resolution->control.number_of_subbands; ++m) + { + /*--------------------------------------------------------*\ + ! Save the subband structure to a temporary variable to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + subband = &resolution->subband[m]; + + for(p = 0; p < resolution->control.number_of_precincts; ++p) + { + for(cb = 0; cb < subband->precinct[p].control.number_of_codeblocks; ++cb) + { + /*--------------------------------------------------------*\ + ! Save the codeblock structure and the coding pass contri- ! + ! bution array to temporary variables to make the code ! + ! readable. ! + \*--------------------------------------------------------*/ + codeblock = &subband->precinct[p].codeblock[cb]; + cp_contr = codeblock->control.cp_contr; + + /*--------------------------------------------------------*\ + ! Loop through all coding passes until the first value is ! + ! reached that is smaller than the prescribed slope thresh-! + ! old. ! + \*--------------------------------------------------------*/ + for(z = codeblock->encoded_block->Z; z >= 0 && codeblock->encoded_block->S[z] < threshold; --z); + + /*--------------------------------------------------------*\ + ! Check if the calculated coding pass has a smaller index ! + ! than the previous quality layer. If true, no additional ! + ! information will be encoded. The coding pass for the ! + ! current quality layer is therefore set to the coding ! + ! pass of the previous quality layer. If no previous qual- ! + ! ity layer has been generated, the length of the first ! + ! coding pass is added to the estimated quality layer ! + ! length. ... ! + \*--------------------------------------------------------*/ + if(z < cp_contr[q_layer - 1]) + { + cp_contr[q_layer] = cp_contr[q_layer - 1]; + + if(cp_contr[q_layer] == 1) + { + estimated_ql_size += codeblock->encoded_block->L[0]; + } + } + /*--------------------------------------------------------*\ + ! If false, the coding pass index is added to the coding ! + ! pass contribution list. If no information has been in- ! + ! cluded in the previous quality layer, or the coding pass ! + ! index is equal to 1, the length of the previous coding ! + ! pass is added to the estimated quality layer length. If ! + ! the previous quality layer contains information, the ! + ! length difference between the two evaluated coding pass- ! + ! es is added. ! + \*--------------------------------------------------------*/ + else + { + cp_contr[q_layer] = z; + + if(z > 0) + { + estimated_ql_size += codeblock->encoded_block->L[z - 1]; + + if(z > 1 && (cp_contr[q_layer - 1] > 0)) + { + estimated_ql_size -= codeblock->encoded_block->L[cp_contr[q_layer - 1] - 1]; + } + } + } + + /*--------------------------------------------------------*\ + ! Check if the current packet has any codeblock contribu- ! + ! tion and set the empty header indicator and its coordi- ! + ! nates accordingly. ! + \*--------------------------------------------------------*/ + if(cp_contr[q_layer] > cp_contr[q_layer - 1]) + { + resolution->packet[q_layer * nPrec + p].e = 1; + } + + /*--------------------------------------------------------*\ + ! If the last, valid quality layer has been correctly cal- ! + ! culated, add the information to the appropriate tagtree. ! + \*--------------------------------------------------------*/ + if(!est) + { + /*--------------------------------------------------------*\ + ! Set the value for the number of non-significant, leading ! + ! bitplanes in the appropriate tagtree. ! + \*--------------------------------------------------------*/ + if(q_layer == 0) + { + tagtree_set_value(subband->precinct[p].control.tag_msbs, cb, codeblock->encoded_block->Kmsbs); + } + + /*--------------------------------------------------------*\ + ! If the last, valid quality layer has been correctly cal- ! + ! culated, add the information to the appropriate tagtree. ! + \*--------------------------------------------------------*/ + if(q_layer + 1 == control->nLayers) + { + for(l = 0; (l < control->nLayers) && (cp_contr[l] == 0); ++l); + + tagtree_set_value(subband->precinct[p].control.tag_inclusion, cb, l); + } + } + } + } + } + + for(p = 0; p < resolution->control.number_of_precincts; ++p) + { + estimated_ph_size = create_packet(field, tile, resolution, p, q_layer, est + 1); + + if(estimated_ph_size < 0) + { + return -1; + } + else + { + estimated_ql_size += estimated_ph_size; + } + + } + } + } + return estimated_ql_size; +} + + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void create_quality_layers(bwc_field *const field, bwc_tile *const tile) ! +! -------------- ! +! ! +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! tile bwc_tile* - Structure defining a bwc tile. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 29.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static uchar +create_quality_layers(bwc_field *const field, bwc_tile *const tile) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 tile_size, header_size; + int64 estimated_tile_size, target_ql_size; + int64 estimated_ql_size; + uint32 main_header_size; + uint16 slope, slope_min, slope_max; + uint16 tmp; + uint8 l; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + bwc_tile_ctrl *tile_control; + bwc_tile_inf *tile_info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(tile); + + /*--------------------------------------------------------*\ + ! Save the global and tile control and info structure to ! + ! temporary variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = field->info; + + tile_control = &tile->control; + tile_info = &tile->info; + + /*--------------------------------------------------------*\ + ! Initialize the target and estimated quality layer size ! + ! and the estimated tile size. ! + \*--------------------------------------------------------*/ + target_ql_size = 0; + estimated_ql_size = 0; + estimated_tile_size = 0; + + /*--------------------------------------------------------*\ + ! Calculate the size of the main header, including the end ! + ! of header marker segment. ! + \*--------------------------------------------------------*/ + main_header_size = control->header.size + 4 + (control->nTiles * info->nPar * 2 * PREC_BYTE); + + /*--------------------------------------------------------*\ + ! Calculate the size of the present tile and the overall ! + ! impact of the codestream headers per quality layer. ! + \*--------------------------------------------------------*/ + tile_size = ((tile_info->X1 - tile_info->X0) * (tile_info->Y1 - tile_info->Y0) * + (tile_info->Z1 - tile_info->Z0) * (tile_info->TS1 - tile_info->TS0)) * (uint64)info->nPar; + + header_size = (uint64)ceilf((float)(main_header_size + tile_control->header_size) / control->nLayers); + + /*--------------------------------------------------------*\ + ! Loop through and create all the user specified quality ! + ! layers. ! + \*--------------------------------------------------------*/ + for(l = 0; l < control->nLayers; ++l) + { + /*--------------------------------------------------------*\ + ! Calculate the size of target size of quality layer l. ! + \*--------------------------------------------------------*/ + target_ql_size = (int64)ceilf(control->bitrate[l] * tile_size / 8.0f); + + if(target_ql_size > 0.0f) + { + slope_min = tile_control->slope_min; + slope_max = tile_control->slope_max; + slope = slope_min; + tmp = slope_min; + + while(slope_min < slope_max) + { + slope = (slope_max + slope_min) >> 1; + + estimated_ql_size = create_quality_layer(field, tile, slope, l, 1); + + if(estimated_ql_size >= 0) + { + estimated_ql_size += estimated_tile_size + header_size; + } + else + { + return 1; + } + + if(estimated_ql_size > target_ql_size) + { + if(slope_min == slope) + { + slope_max = slope; + } + slope_min = slope; + } + else if(estimated_ql_size < target_ql_size) + { + if(slope_max == slope) + { + slope_min = slope; + } + slope_max = slope; + tmp = slope; + } + else + { + slope_max = slope; + slope_min = slope; + } + } + + if(estimated_ql_size > target_ql_size) + { + slope = MAX(tmp, tile_control->slope_min); + } + } + else + { + slope = 0; + } + + estimated_ql_size = create_quality_layer(field, tile, slope, l, 0); + + if(estimated_ql_size >= 0) + { + estimated_tile_size += estimated_ql_size + header_size; + } + else + { + return 1; + } + } + return 0; +} + +/************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar t2_encode(bwc_field *const field, bwc_tile *const tile) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function defines the rate control portion of the entropy encoding stage. In ! +! the first step, the quality layers are evaluated according to the bitrates de- ! +! fined by the user. The quality layers are then used to create the data packets ! +! that comprise the bwc codestream. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! tile bwc_tile* - Structure defining a bwc tile. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 12.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +t2_encode(bwc_field *const field, bwc_tile *const tile) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(tile); + + /*--------------------------------------------------------*\ + ! Create the quality layers according to the bitrate val- ! + ! ues provided by the user. ! + \*--------------------------------------------------------*/ + if(create_quality_layers(field, tile)) + { + return 1; + } + + /*--------------------------------------------------------*\ + ! Create the data packets according to the quality layers ! + ! evaluated in the previous step. ! + \*--------------------------------------------------------*/ + if(create_packets(field, tile)) + { + return 1; + } + + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: uchar parse_packet(bwc_field *const field, bwc_tile *const tile, ! +! -------------- bwc_packet *const packet, ! +! uint64 const body_size) ! +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to parse a codestream packet for a given precinct (prec_idx) ! +! and quality layer (q_layer). ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining the compression/ ! +! decompression stage. ! +! ! +! tile bwc_tile* - Structure defining a bwc tile. ! +! ! +! packet bwc_packet* - Structure defining a bwc packet. ! +! ! +! body_size unsigned int(64 bit) - Size of the remaining bwc codestream. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 29.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +parse_packet(bwc_field *const field, bwc_tile *const tile, + bwc_packet *const packet, + uint64 const body_size) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint32 size, start, end; + uint32 k; + uint16 cb; + int16 *cp_contr; + int16 delta_z; + int8 m; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_resolution *resolution; + bwc_precinct *precinct; + bwc_codeblock *codeblock; + bwc_encoded_cblk *encoded_block; + bwc_stream *header; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(tile); + assert(packet); + + resolution = &tile->parameter[packet->c].resolution[packet->r]; + + /*--------------------------------------------------------*\ + ! Initialize the stream that is used to parse the packet ! + ! codestream. ! + \*--------------------------------------------------------*/ + header = bwc_init_stream(packet->header.memory, body_size, 'd'); + if(!header) + { + // memory allocation error + return 1; + } + + /*--------------------------------------------------------*\ + ! Extract the codeblock contribution marker from the code- ! + ! stream. ! + \*--------------------------------------------------------*/ + packet->e = bwc_get_bit(header); + + /*--------------------------------------------------------*\ + ! Check if the current packet has any codeblock contribu- ! + ! tion. ! + \*--------------------------------------------------------*/ + if(packet->e) + { + /*--------------------------------------------------------*\ + ! Iterate over all codeblocks in all subbands to parse the ! + ! the packet header and body. ! + \*--------------------------------------------------------*/ + for(m = 0; m < resolution->control.number_of_subbands; ++m) + { + /*--------------------------------------------------------*\ + ! Save the precinct structure to a temporary variable to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + precinct = &resolution->subband[m].precinct[packet->p]; + + for(cb = 0; cb < precinct->control.number_of_codeblocks; ++cb) + { + /*--------------------------------------------------------*\ + ! Save the codeblock and coding pass contribution struc- ! + ! tures to temporary variables to make the code more ! + ! readable. ! + \*--------------------------------------------------------*/ + codeblock = &precinct->codeblock[cb]; + cp_contr = codeblock->control.cp_contr; + + /*--------------------------------------------------------*\ + ! Initialize the coding passes present in the packet body ! + ! for the current quality layer. ! + \*--------------------------------------------------------*/ + delta_z = 0; + + /*--------------------------------------------------------*\ + ! Evaluate if the current codeblock already contributed to ! + ! a packet. ! + \*--------------------------------------------------------*/ + if(cp_contr[packet->l - 1] == 0) + { + /*--------------------------------------------------------*\ + ! If no contribution has yet been made, decode the inclu- ! + ! sion tagtree for the current codeblock and... ! + \*--------------------------------------------------------*/ + decode_tagtree(precinct->control.tag_inclusion, header, packet->l + 1, cb); + + /*--------------------------------------------------------*\ + ! Check if the codeblock has any contributions to the cur- ! + ! rent packet. If true, decode the tagtree for the none- ! + ! significant bit planes. ! + \*--------------------------------------------------------*/ + if(tagtree_get_value(precinct->control.tag_inclusion, cb) <= packet->l) + { + delta_z = 1; + k = 1; + + while(decode_tagtree(precinct->control.tag_msbs, header, k++, cb)); + + codeblock->encoded_block->Kmsbs = tagtree_get_value(precinct->control.tag_msbs, cb); + } + } + else + { + /*--------------------------------------------------------*\ + ! If a contribution has already been made, extract the ! + ! flag from the codestream that signals if new coding pas- ! + ! ses are available. ! + \*--------------------------------------------------------*/ + delta_z = bwc_get_bit(header); + } + + + /*--------------------------------------------------------*\ + ! Initialize the current quality layer with the number of ! + ! coding pass contributions present in the previous qual- ! + ! ity layer. ! + \*--------------------------------------------------------*/ + cp_contr[packet->l] = cp_contr[packet->l - 1]; + + /*--------------------------------------------------------*\ + ! Check if new coding passes contributions are available. ! + \*--------------------------------------------------------*/ + if(delta_z) + { + /*--------------------------------------------------------*\ + ! If new coding passes are available, decode delta_z, ... ! + \*--------------------------------------------------------*/ + decode_delta_z(header, delta_z); + + /*--------------------------------------------------------*\ + ! ... add the additional coding passes to the current qual-! + ! ity layer and update the maximum number of coding passes ! + ! of the current codeblock... ! + \*--------------------------------------------------------*/ + cp_contr[packet->l] += delta_z; + codeblock->encoded_block->Z = cp_contr[packet->l]; + + /*--------------------------------------------------------*\ + ! ... and decode the corresponding coding pass lengths. ! + \*--------------------------------------------------------*/ + decode_length(header, codeblock, packet->l); + } + } + } + } + else + { + /*--------------------------------------------------------*\ + ! Iterate over all codeblocks in all subbands. ! + \*--------------------------------------------------------*/ + for(m = 0; m < resolution->control.number_of_subbands; ++m) + { + /*--------------------------------------------------------*\ + ! Save the precinct structure to a temporary variable to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + precinct = &resolution->subband[m].precinct[packet->p]; + + for(cb = 0; cb < precinct->control.number_of_codeblocks; ++cb) + { + /*--------------------------------------------------------*\ + ! Save the codeblock and coding pass contribution struc- ! + ! tures to temporary variables to make the code more ! + ! readable. ! + \*--------------------------------------------------------*/ + codeblock = &precinct->codeblock[cb]; + cp_contr = codeblock->control.cp_contr; + + /*--------------------------------------------------------*\ + ! Initialize the current quality layer with the number of ! + ! coding pass contributions present in the previous qual- ! + ! ity layer. ! + \*--------------------------------------------------------*/ + cp_contr[packet->l] = cp_contr[packet->l - 1]; + } + } + } + + /*--------------------------------------------------------*\ + ! If the header size has not already been evaluated, safe ! + ! the number of used bytes in the appropriate variable. ! + \*--------------------------------------------------------*/ + if(!packet->header.size) + { + packet->header.size = bytes_used(header); + } + + /*--------------------------------------------------------*\ + ! If the packet body memory handle has not been set, safe ! + ! the current position in the header stream in the memory ! + ! and access variables. ! + \*--------------------------------------------------------*/ + if(!packet->body.memory) + { + packet->body.access = + packet->body.memory = get_access(header); + } + + /*--------------------------------------------------------*\ + ! Free the packet header stream. ! + \*--------------------------------------------------------*/ + free(header); + + /*--------------------------------------------------------*\ + ! If the error resilience mode is active for the current ! + ! codestream... ! + \*--------------------------------------------------------*/ + if(field->control.error_resilience) + { + /*--------------------------------------------------------*\ + ! check if the next symbol corresponds to the end of pack- ! + ! header (EOH) marker... ! + \*--------------------------------------------------------*/ + if(packet->body.memory[0] != 0xFF || + packet->body.memory[1] != 0x92) + { + /*--------------------------------------------------------*\ + ! ... If not, return to the function caller with an error ! + ! marker. ! + \*--------------------------------------------------------*/ + return 1; + } + else + { + /*--------------------------------------------------------*\ + ! ... If true, advance the packet body memory and access ! + ! pointer and increase the header size by 2 bytes. ! + \*--------------------------------------------------------*/ + packet->body.access = + packet->body.memory += 2; + packet->header.size += 2; + } + } + + /*--------------------------------------------------------*\ + ! Check if the current packet has any codeblock contribu- ! + ! tion. ! + \*--------------------------------------------------------*/ + if(packet->e) + { + /*--------------------------------------------------------*\ + ! Iterate over all codeblocks in all subbands. ! + \*--------------------------------------------------------*/ + for(m = 0; m < resolution->control.number_of_subbands; ++m) + { + /*--------------------------------------------------------*\ + ! Save the precinct structure to a temporary variable to ! + ! make the code more readable. ! + \*--------------------------------------------------------*/ + precinct = &resolution->subband[m].precinct[packet->p]; + + for(cb = 0; cb < precinct->control.number_of_codeblocks; ++cb) + { + /*--------------------------------------------------------*\ + ! Save the codeblock, encoded codeblock and coding pass ! + ! contribution structures to temporary variables to make ! + ! the code more readable. ! + \*--------------------------------------------------------*/ + codeblock = &precinct->codeblock[cb]; + encoded_block = codeblock->encoded_block; + cp_contr = codeblock->control.cp_contr; + + /*--------------------------------------------------------*\ + ! Check if new contributions are available. ! + \*--------------------------------------------------------*/ + if(cp_contr[packet->l] > cp_contr[packet->l - 1]) + { + /*--------------------------------------------------------*\ + ! Evaluate the start and end position, as well as the size ! + ! of the new contribution in the encoded codeblock memory ! + ! block and. ! + \*--------------------------------------------------------*/ + start = (cp_contr[packet->l - 1] == 0) ? 0 : codeblock->encoded_block->L[cp_contr[packet->l - 1] - 1]; + end = (cp_contr[packet->l] == 0) ? 0 : codeblock->encoded_block->L[cp_contr[packet->l] - 1]; + size = end - start; + + /*--------------------------------------------------------*\ + ! Reallocate the encoded codeblock memory block to accomo- ! + ! date the coding pass contribution. ! + \*--------------------------------------------------------*/ + encoded_block->data = realloc(encoded_block->data, end + size); + if(!encoded_block->data) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return 1; + } + + /*--------------------------------------------------------*\ + ! Copy the data to the encoded block structure. ! + \*--------------------------------------------------------*/ + memcpy(codeblock->encoded_block->data + start, packet->body.access, size); + + /*--------------------------------------------------------*\ + ! Advance the packet body access pointer to the next cod- ! + ! ing pass contribution and increase the packet body size ! + ! accordingly. ! + \*--------------------------------------------------------*/ + packet->body.access += size; + packet->body.size += size; + } + } + } + } + + /*--------------------------------------------------------*\ + ! Evaluate the packet size and return to the function ! + ! caller. ! + \*--------------------------------------------------------*/ + packet->size = packet->header.size + packet->body.size; + return 0; +} \ No newline at end of file diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt new file mode 100755 index 0000000..b05db0f --- /dev/null +++ b/src/tools/CMakeLists.txt @@ -0,0 +1,93 @@ +#*====================================================================================================================*# +#| |# +#| /$$$$$$$ /$$ /$$ /$$ /$$ |# +#| | $$__ $$|__/ | $$ /$ | $$| $$ |# +#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# +#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# +#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# +#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# +#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# +#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# +#| /$$ \ $$ | $$ |# +#| | $$$$$$/ | $$ |# +#| \______/ |__/ |# +#| DESCRIPTION: |# +#| ------------ |# +#| Defines the cmake script for the BigWhoop command line tool. |# +#| |# +#| |# +#| DEVELOPMENT HISTORY: |# +#| -------------------- |# +#| |# +#| Date Author Change Id Release Description Of Change |# +#| ---- ------ --------- ------- --------------------- |# +#| 30.08.2018 Patrick Vogler B87D120 V 0.1.0 cmake file created |# +#| 15.10.2021 Patrick Vogler B880CA2 V 0.1.1 Added install rules |# +#| |# +#| |# +#| ------------------------------------------------------------------------------------------------------ |# +#| |# +#| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart |# +#| |# +#| Redistribution and use in source and binary forms, with or without modification, are permitted |# +#| provided that the following conditions are met: |# +#| |# +#| (1) Redistributions of source code must retain the above copyright notice, this list of |# +#| conditions and the following disclaimer. |# +#| |# +#| (2) Redistributions in binary form must reproduce the above copyright notice, this list |# +#| of conditions and the following disclaimer in the documentation and/or other materials |# +#| provided with the distribution. |# +#| |# +#| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED |# +#| WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |# +#| PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR |# +#| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |# +#| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |# +#| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR |# +#| TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |# +#| ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |# +#| |# +#*====================================================================================================================*# +#*--------------------------------------------------------*# +# Add the bwc command line utility and get hash tool to # +# the current project using the utility source files. # +#*--------------------------------------------------------*# +add_executable(bwccmd bwccmdl.c + ../interfaces/reader/eas3.c) + +#*--------------------------------------------------------*# +# Set the target compile definition for the requested file # +# format support. # +#*--------------------------------------------------------*# +MESSAGE(STATUS "EAS3 file format support: ${BUILD_EAS3}") + +if(${BUILD_EAS3}) + target_compile_definitions(bwccmd PRIVATE -DBWC_EAS3) +endif() + +if(${BUILD_NETCDF}) + target_compile_definitions(bwccmd PRIVATE -DBWC_NETCDF) +endif() + +#*--------------------------------------------------------*# +# Define the output name for the utility binaries. # +#*--------------------------------------------------------*# +set_property(TARGET bwccmd PROPERTY OUTPUT_NAME bwc) + +#*--------------------------------------------------------*# +# Setup up the include directory for the bwc utilities. # +#*--------------------------------------------------------*# +target_include_directories(bwccmd PRIVATE ${CMAKE_SOURCE_DIR}/include/tools) +target_include_directories(bwccmd PRIVATE ${CMAKE_SOURCE_DIR}/include/library/public) +target_include_directories(bwccmd PRIVATE ${CMAKE_SOURCE_DIR}/include/interfaces/reader) + +#*--------------------------------------------------------*# +# Setup the install directories. # +#*--------------------------------------------------------*# +install(TARGETS bwccmd DESTINATION ${CMAKE_INSTALL_BINDIR}) + +#*--------------------------------------------------------*# +# Link the bwc utility to the bwc library. # +#*--------------------------------------------------------*# +target_link_libraries(bwccmd PRIVATE bwclib m) \ No newline at end of file diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c new file mode 100755 index 0000000..e2fc98e --- /dev/null +++ b/src/tools/bwccmdl.c @@ -0,0 +1,3243 @@ +/*====================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This is a simple command line tool that uses the Big Whoop library to (de)com- || +|| press a 2- to 4-dimensional IEEE 754 floating point array. For further infor- || +|| mation use the --help (-h) argument in the command-line or consult the appro- || +|| priate README file. || +|| || +|| FILE REFERENCES: || +|| ---------------- || +|| || +|| Name I/O Description || +|| ---- --- ----------- || +|| - input - input - Input file that corresponds to || +|| an uncompressed dataset, for a || +|| compression run, or a com- || +|| pressed bitstream, for a decom- || +|| pression run. || +|| || +|| - output - Output - Output file that the com- || +|| pressed bitstream, for a com- || +|| pression run, or reconstructed || +|| dataset, for a decompression || +|| run, is written to. || +|| || +|| FUNCTIONS: || +|| ---------- || +|| || +|| PRIVATE: PUBLIC: || +|| -------- ------- || +|| - get_digit_sep - main || +|| - get_size || +|| - get_dimension || +|| - get_prog_ord || +|| - get_quant_style || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 13.10.2017 Patrick Vogler B87D120 V 0.1.0 source file created || +|| 26.11.2020 Patrick Vogler B87E7E4 V 0.1.0 Command line tool refac- || +|| tored. || +|| || +|| || +|| ------------------------------------------------------------------------------------------------------ || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted || +|| provided that the following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of || +|| conditions and the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list || +|| of conditions and the following disclaimer in the documentation and/or other materials || +|| provided with the distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED || +|| WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A || +|| PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR || +|| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT || +|| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS || +|| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR || +|| TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF || +|| ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*====================================================================================================================*/ +/**********************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\**********************************************************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bwccmdl.h" +#include "eas3.h" + +/**********************************************************************************************************************\ +|| ____ _ ____ ___ ____ _ ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || +|| | __ | | | |__] |__| | | | | |\ | [__ | |__| |\ | | [__ || +|| |__] |___ |__| |__] | | |___ |___ |__| | \| ___] | | | | \| | ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This array defines the arguments supported by the bwc command line tool. Each ! +! argument follows the following structure: ! +! ! +! | flag | long name | short name | opt | type | example | description | ! +! ! +! The flag signals if the argument is active, while the opt and type string def- ! +! ine the argument type and wether it is optional. Finally, the example string ! +! is 24 characters long and highlights how the argument is to be used while the ! +! description should be no longer than 1024 and contain the argument description. ! +! Additionally, the description needs to be subdivided into blocks of 50 charac- ! +! ters for formating. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 09.07.2019 Patrick Vogler B87D120 V 0.1.0 Constant created. ! +! 03.05.2021 Patrick Vogler B87E7E4 V 0.1.0 Description updated. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static bwc_cmdl_args CMDL_ARGS[] = { +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "compress", "c", "arg", "str1", "-c", "Compress a numerical dataset."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "decompress", "d", "arg", "str1", "-d", "Decompress a BigWhoop file."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "analysis", "al", "arg", "lit", "-al", "Analyze the Peak Signal to Noise Ratio (PSNR) and " + "Mean Square Error (MSE) of a decompressed dataset."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "info", "if", "arg", "str1", "-if", "Display the header information of a BigWhoop file."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "help", "h", "arg", "lit", "-h", "Print this help message and exit."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "input", "i", "arg", "str1", "-i /path/to/input", "Valid path to a file that can be parsed/read by " + "this command line tool. For a full list of the " + "supported file extension see the bottom of this " + "message."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "output", "o", "arg", "str1", "-o /path/to/output", "Valid path and filename that defines the output of" + "the (de)compressed dataset. If not defined, the " + "[input] argument is used to generate the (de)com- " + "pressed output."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "reference", "rf", "arg", "str1", "-rf /path/to/output", "Valid path to a file that is used as a reference " + "for the [analysis] option."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "verbose", "v", "opt", "num1", "-v *", "Displays miscellaneous information. This option " + "accepts the value 0 (default) for compression sta-" + "tistics and 1 for the applied compression param. "}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "bitrate", "b", "opt", "numl", "-b *, *, *...", "Defines the quality layers present in the code- " + "stream as a function of the average bits per data " + "point. This option accepts real numbers in the " + "range of 0 < * < 64."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "codeblock_size", "cb", "opt", "num4", "-cb x=* y=* z=* ts=*", "Defines the codeblocks size for all dimensions and" + "timesteps. This option accepts natural numbers in " + "log2 format in the range of 1 <= * <= 10. The sum " + "of all values has to lie within the range of " + "4 < sum* < 20."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "compression_ratio", "cr", "opt", "num1", "-cr *", "Defines the ratio between the uncompresssed and " + "uncompressed file size. This option accepts all " + "positive real numbers."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "decomposition_levels", "dl", "opt", "num4", "-dl x=* y=* z=* ts=*", "Deefines the number of wavelet decompositions ap- " + "plied to all dimensions and timesteps. This option" + "accepts natural numbers in the range of 1 <= * <= " + "63."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "number_of_threads", "n", "opt", "num1", "-n *", "Defines the number of OpenMP threads used to (de) " + "compress the [input] file. This option accepts " + "natural numbers in the range of 1 <= * <= 255. "}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "layer", "l", "opt", "num1", "-l *", "Defines the quality layer used to generate the nu-" + "merical dataset from the bwc codestream. This op- " + "tion accepts natural numbers in the range of 0 < " + "* <= number_of_quality_layers."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{0, "wavelet_kernels", "k", "opt", "str4", "-k x=* y=* z=* ts=*", "Ddefines the wavelet kernels applied to all dimen-" + "sions and timesteps. This option accepts the " + "strings CDF, LeGall and Haar."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{0, "quantisation_step_size", "q", "opt", "num1", "-q *", "Defines the step size of the quantization applied " + "to the wavelet coefficients. This option accepts " + "real numbers in the range of 0 < * < 2."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "q_format_range", "qm", "opt", "num1", "-qm *", "Defines the Q format's number of fractional bits " + "used to transform the floating to a fixed point " + "format. This option accepts natural numbers in the" + "range of 1 <= * <= 62."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "error_resilience", "r", "opt", "lit", "-r", "The [error_resilience] option is used to place " + "special markers in the compressed bitstream that " + "help with error detection and limit error propaga-" + "tion."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "tile_size", "t", "opt", "num4", "-t x=* y=* z=* ts=*", "Defines the tile size for all dimensions and time-" + "steps of a tile. This option accepts natural num- " + "bers in the range of 16 <= * <= domain size."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{1, "precinct_size", "p", "opt", "num4", "-p x=* y=* z=* ts=*", "Defines the precinct size for all dimensions and " + "timesteps. This option accepts natural numbers in " + "log2 format in the range of 1 <= * <= 15."}, +//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| +{0, "", "", "end", "", "", ""}}; + +/**********************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function converts the endianess of half, single or double precision values. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! value void* - Memory address of the parame- ! +! ter to be converted. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 30.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 21.11.2019 Patrick Vogler B87E7E4 V 0.1.0 functionality expanded ! +! to 32 bit integers ! +! 21.11.2019 Patrick Vogler B87E7E4 V 0.1.0 functionality expanded ! +! to 16 bit integers ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +static void +endian_conversion(void *value, + uint8_t const accuracy) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(value); + + switch(accuracy) + { + case 2: + { + uint16_t *tmp = (uint16_t*)value; + + *tmp = (uint16_t)( *tmp << 8) | + (uint16_t)( *tmp >> 8); + break; + } + + case 4: + { + uint32_t *tmp = (uint32_t*)value; + + *tmp = (uint32_t)((*tmp << 8) & 0xFF00FF00) | + (uint32_t)((*tmp >> 8) & 0x00FF00FF); + + *tmp = (uint32_t)( *tmp << 16) | + (uint32_t)( *tmp >> 16); + break; + } + + case 8: + { + uint64_t *tmp = (uint64_t*)value; + + *tmp = (uint64_t)((*tmp << 8) & 0xFF00FF00FF00FF00ULL) | + (uint64_t)((*tmp >> 8) & 0x00FF00FF00FF00FFULL); + + *tmp = (uint64_t)((*tmp << 16) & 0xFFFF0000FFFF0000ULL) | + (uint64_t)((*tmp >> 16) & 0x0000FFFF0000FFFFULL); + + *tmp = (uint64_t)( *tmp << 32) | + (uint64_t)( *tmp >> 32); + break; + } + default: + { + break; + } + } +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function takes a command line argument, checks if it is hyphenated and, ! +! if true, returns a pointer to the first valid character in the string. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! str char* - String containing a command ! +! line argument. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! char* - Pointer to a hyphenated com- ! +! mand line argument. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 03.05.2021 Patrick Vogler B87D120 V 0.1.0 function created ! +! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static char* +get_opt(char* str) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + size_t trim; + + trim = strspn(str, " "); + + if((trim < strlen(str)) && (str[trim] == '-')) + return &str[trim]; + else + return NULL; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function takes an integer value, generates a version with proper digital ! +! group separators and returns the string to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! integer unsigned int(64 bit) - Integer value. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! char* - Character array containing the ! +! group seperated integer value. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 03.02.2020 Patrick Vogler B87D120 V 0.1.0 function created ! +! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static char* +get_digit_sep(uint64_t integer) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64_t multiplier; + uint16_t buffI; + uint8_t length, shift; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char buffC[7] = {0}; + char *str; + + /*--------------------------------------------------------*\ + ! Calculate the decimal power of the integer value, esti- ! + ! mate the length of the group seperated string and alloc- ! + ! cate the corresponding character array. ! + \*--------------------------------------------------------*/ + shift = (uint8_t)log10(integer); + length = (uint8_t)floor(shift/3.0f) + shift + 2; + + str = calloc(length, sizeof(char)); + if(str == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Iterate over the integer value and assemble the group ! + ! serparated string. ! + \*--------------------------------------------------------*/ + do + { + /*--------------------------------------------------------*\ + ! If the first digits do not form a group, decrement the ! + ! shift to the next group, extract the first digits from ! + ! the integer and write them to the string. ! + \*--------------------------------------------------------*/ + if(shift % 3 || shift == 0) + { + shift -= (shift % 3); + multiplier = (uint64_t)pow(10, shift); + buffI = integer/multiplier; + integer -= (uint64_t)buffI * multiplier; + + sprintf(buffC, "%d", buffI); + strcat(str, buffC); + memset(buffC, '\0', 5); + } + /*--------------------------------------------------------*\ + ! If the next digits form a group, decrement the decimal ! + ! shift, extract digits from the integer and write them ! + ! to the string with the proper separator. ! + \*--------------------------------------------------------*/ + else + { + shift -= 3; + multiplier = (uint64_t)pow(10, shift); + buffI = integer/multiplier; + integer -= (uint64_t)buffI * multiplier; + if(strlen(str)) + { + sprintf(buffC, ".%03d", buffI); + } + else + { + sprintf(buffC, "%03d", buffI); + } + strcat(str, buffC); + memset(buffC, '\0', 5); + } + } while(shift); + return str; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function takes an integer value and generates a version with the appropri- ! +! ate byte unit in log2 format that is returned to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! integer unsigned int(64 bit) - Integer value. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! char* - Character array containing ! +! the group seperated string. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 03.05.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static char* +get_size(uint64_t integer) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64_t multiplier; + uint8_t i; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char *sizes[] = { "EiB", "PiB", "TiB", "GiB", "MiB", "KiB", "B" }; + char *str; + + /*--------------------------------------------------------*\ + ! Set up the multiplier used to evaluate the digital unit ! + ! prefix and allocate the character array returned to the ! + ! function caller. ! + \*--------------------------------------------------------*/ + multiplier = 1024ULL * 1024ULL * 1024ULL * + 1024ULL * 1024ULL * 1024ULL; + + str = calloc(10, sizeof(char)); + if(str == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return NULL; + } + + /*--------------------------------------------------------*\ + ! If larger than 0, iterate over the byte units until the ! + ! integer is within its range and populate the char. array ! + ! with the appropriate information. ! + \*--------------------------------------------------------*/ + if(integer > 0) + { + for(i = 0; i < 7; ++i, multiplier /= 1024) + { + if(integer < multiplier) + continue; + if(integer % multiplier == 0) + sprintf(str, "%" PRIu64 " %s", integer / multiplier, sizes[i]); + else + sprintf(str, "%.1f %s", floor((10.0 * integer) / multiplier) / 10.0, sizes[i]); + break; + } + } + else + { + strcpy(str, "0 B"); + } + return str; +} + + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is a variant of the DJB hash function that takes a string, con- ! +! verts it to uppercase and returns the appropriate hash. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! str char* - String used to generate a u- ! +! niquely identifiable hash. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uint64_t - Uniquely identifiable hash. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 17.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static uint64_t +hash(char* str) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64_t hash; + uint8_t c; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(str); + + /*--------------------------------------------------------*\ + ! Initialize the hash with a magic number. ! + \*--------------------------------------------------------*/ + hash = 0x1505; + + /*--------------------------------------------------------*\ + ! Walk through all the characters in the string, convert ! + ! them to uppercase and use them to generate the hash. ! + \*--------------------------------------------------------*/ + while((c = *str++)) + { + if((c >= 97) && + (c <= 122)) + { + c = c - 32; + } + + hash = (hash * 33) ^ c; + } + + /*--------------------------------------------------------*\ + ! Return the hash. ! + \*--------------------------------------------------------*/ + return hash; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function deallocates a util_arg_node linked list that is used to store ! +! the bwc command line arguments. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! args util_arg_node* - Arguments/options linked list ! +! for the bwc command-line tool. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 24.04.2019 Patrick Vogler B87D120 V 0.1.0 Function created ! +! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static void +bwc_kill_arg(bwc_cmdl_arg_node *args) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_cmdl_arg_node *temp; + + if(args != NULL) + { + /*--------------------------------------------------------*\ + ! Reset the arguments linked list to its root node. ! + \*--------------------------------------------------------*/ + args = args->root; + + /*--------------------------------------------------------*\ + ! Walk through the arguments linked list and deallocate ! + ! the lit_opt, num_ opt and util_arg_node structure. ! + \*--------------------------------------------------------*/ + while(args != NULL) + { + temp = args; + args = args->next; + + free(temp->lit_opt); + free(temp->num_opt); + free(temp); + } + } +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to parse the command-line arguments, check if they are ! +! valid arguments and options for the bwc command-line tool and save them in a ! +! linked list. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! argc int - Argument count ! +! ! +! argv char** - Argument vector ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! util_arg_node* - Arguments/options linked list ! +! for the bwc command-line tool. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 17.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static bwc_cmdl_arg_node* +parse_arguments(int argc, + char **argv) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64_t buf; + uint64_t *hash_list; + uint64_t *tmp; + + uint16_t l, lsiz; + + uint8_t i, j; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char *token, *ptr; + char *str; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_cmdl_arg_node *args; + + /*--------------------------------------------------------*\ + ! Allocate an integer array used to store the hash values ! + ! for all active command line arguments and options. ! + \*--------------------------------------------------------*/ + hash_list = calloc(40, sizeof(uint64_t)); + if(hash_list == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Loop through the command line argument list and store ! + ! the hash value of the long and short name for all active ! + ! command line arguments in the hash list. ! + \*--------------------------------------------------------*/ + for(l = 0, lsiz = 20; strcmp(CMDL_ARGS[l].arg_type, "end"); ++l) + { + if(l >= lsiz) + { + lsiz *= 2; + hash_list = realloc(hash_list, lsiz * 2 * sizeof(uint64_t)); + if(hash_list == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return NULL; + } + } + + hash_list[2 * l] = hash(CMDL_ARGS[l].arg_long); + hash_list[2 * l + 1] = hash(CMDL_ARGS[l].arg_short); + } + + /*--------------------------------------------------------*\ + ! Save the total number of active command line arguments, ! + ! reallocate the corresponding hash list and initialize ! + ! the arguments linked list. ! + \*--------------------------------------------------------*/ + lsiz = l; + tmp = realloc(hash_list, lsiz * 2 * sizeof(uint64_t)); + if(tmp == NULL) + { + // memory allocation error + free(hash_list); + fprintf(stderr, MEMERROR); + return NULL; + } + else + { + hash_list = tmp; + } + + args = calloc(1, sizeof(bwc_cmdl_arg_node)); + if(args == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return NULL; + } + args->root = args; + + /*--------------------------------------------------------*\ + ! Walk through all the command-line arguments passed to ! + ! main. ! + \*--------------------------------------------------------*/ + for(i = 0; i < argc; ++i) + { + /*--------------------------------------------------------*\ + ! Check if the command-line argument is hyphenated, indi- ! + ! cating a bwc argument or option. If this is the case, ! + ! save a pointer to the argument in a temporary variable. ! + \*--------------------------------------------------------*/ + str = get_opt(argv[i]); + + if(str) + { + /*--------------------------------------------------------*\ + ! Generate a hash from the argument string. ! + \*--------------------------------------------------------*/ + buf = hash(++str); + + /*--------------------------------------------------------*\ + ! Check if the command-line argument is a valid bwc argu- ! + ! ment or option and if additional values are expected for ! + ! the current argument or option. The additional values ! + ! are handled according to the type of the current argu- ! + ! ment. ! + \*--------------------------------------------------------*/ + for(l = 0; l < lsiz; ++l) + { + if(buf == hash_list[2 * l] || buf == hash_list[2 * l + 1]) + { + switch(hash(CMDL_ARGS[l].type)) + { + /*--------------------------------------------------------*\ + ! This type of argument/option requires no additional in- ! + ! formation and the parser can advance to the next hyphen- ! + ! ated command-line argument. ! + \*--------------------------------------------------------*/ + case 0x000000000B87DB14: + { + /*--------------------------------------------------------*\ + ! Store the hash identifier in the linked list node. ! + \*--------------------------------------------------------*/ + args->hash = hash_list[2 * l]; + break; + } + + /*--------------------------------------------------------*\ + ! This type of argument/option accepts a single string ! + ! that is passed to the parser as a non-hyphenated ! + ! command-line argument. ! + \*--------------------------------------------------------*/ + case 0x000000017C8A3F41: + { + /*--------------------------------------------------------*\ + ! Store the hash identifier in the linked list node. ! + \*--------------------------------------------------------*/ + args->hash = hash_list[2 * l]; + + /*--------------------------------------------------------*\ + ! Check that the next command-line argument is non-hypenat-! + ! ed. If true, allocate the lit_opt character array and ! + ! store the arguments memory handle. ! + \*--------------------------------------------------------*/ + if(((i + 1) < argc) && (get_opt(argv[i + 1]) == NULL)) + { + args->lit_opt = calloc(args->count + 1, sizeof(char*)); + if(args->lit_opt == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_kill_arg(args); + free(hash_list); + return NULL; + } + args->lit_opt[args->count++] = argv[i + 1]; + } + break; + } + + /*--------------------------------------------------------*\ + ! This type of argument/option accepts four additional ! + ! strings that are passed to parser as a non-hyphenated ! + ! command-line arguments. ! + \*--------------------------------------------------------*/ + case 0x000000017C8A3F44: + { + /*--------------------------------------------------------*\ + ! Store the hash identifier in the linked list node. ! + \*--------------------------------------------------------*/ + args->hash = hash_list[2 * l]; + + /*--------------------------------------------------------*\ + ! Loop through the next four command-line arguments, check ! + ! that they are non-hyphenated and, if true, store their ! + ! memory handle in the list node. ! + \*--------------------------------------------------------*/ + for(j = i + 1; j < argc && (get_opt(argv[j]) == NULL); ++j) + { + /*--------------------------------------------------------*\ + ! Allocate the lit_opt array for 4 character strings. ! + \*--------------------------------------------------------*/ + if(args->lit_opt == NULL) + { + args->lit_opt = calloc(4, sizeof(char*)); + if(args->lit_opt == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_kill_arg(args); + free(hash_list); + return NULL; + } + args->count = 0x04; + } + + /*--------------------------------------------------------*\ + ! Save the memory handle for the next argument in a tempo- ! + ! rary variable and tokenize the string according to the ! + ! specified delimiters. ! + \*--------------------------------------------------------*/ + str = argv[j]; + token = strtok_r(str, ":=\t, ", &ptr); + + /*--------------------------------------------------------*\ + ! Check if a valid token has been generated for the first ! + ! spatial direction. If true, save the memory handle, set ! + ! the dimension flag and generate the next token. ! + \*--------------------------------------------------------*/ + if(token && ((strchr(token, 'x') != NULL) || + (strchr(token, 'X') != NULL))) + { + token = strtok_r(NULL, ":=\t, ", &ptr); + args->lit_opt[0] = token; + args->dim |= 0x01; + token = strtok_r(NULL, ":=\t, ", &ptr); + } + + /*--------------------------------------------------------*\ + ! Check if a valid token has been generated for the second ! + ! spatial direction. If true, save the memory handle, set ! + ! the dimension flag and generate the next token. ! + \*--------------------------------------------------------*/ + if(token && ((strchr(token, 'y') != NULL) || + (strchr(token, 'Y') != NULL))) + { + token = strtok_r(NULL, ":=\t, ", &ptr); + args->lit_opt[1] = token; + args->dim |= 0x02; + token = strtok_r(NULL, ":=\t, ", &ptr); + } + + /*--------------------------------------------------------*\ + ! Check if a valid token has been generated for the third ! + ! spatial direction. If true, save the memory handle, set ! + ! the dimension flag and generate the next token. ! + \*--------------------------------------------------------*/ + if(token && ((strchr(token, 'z') != NULL) || + (strchr(token, 'Z') != NULL))) + { + token = strtok_r(NULL, ":=\t, ", &ptr); + args->lit_opt[2] = token; + args->dim |= 0x04; + token = strtok_r(NULL, ":=\t, ", &ptr); + } + + /*--------------------------------------------------------*\ + ! Check if a valid token has been generated for the first ! + ! temporal direction. If true, save the memory handle, set ! + ! the dimension flag and generate the next token. ! + \*--------------------------------------------------------*/ + if(token && ((strchr(token, 't') != NULL) || + (strchr(token, 'T') != NULL))) + { + token = strtok_r(NULL, ":=\t, ", &ptr); + args->lit_opt[3] = token; + args->dim |= 0x08; + token = strtok_r(NULL, ":=\t, ", &ptr); + } + } + break; + } + + /*--------------------------------------------------------*\ + ! This type of argument/option accepts a single numerical ! + ! value that is passed to parser as a non-hyphenated com- ! + ! mand-line argument. ! + \*--------------------------------------------------------*/ + case 0x000000017C82A8C2: + { + /*--------------------------------------------------------*\ + ! Store the hash identifier in the linked list node. ! + \*--------------------------------------------------------*/ + args->hash = hash_list[2 * l]; + + /*--------------------------------------------------------*\ + ! Check that the next command-line argument is non-hypenat-! + ! ed and a valid floating point value. If true, allocate ! + ! the num_opt array and store the real value in it. ! + \*--------------------------------------------------------*/ + if(((i + 1) < argc) && (get_opt(argv[i + 1]) == NULL)) + { + str = argv[i + 1]; + + if(strtof(str, NULL) > 0.0f) + { + args->num_opt = calloc(args->count + 1, sizeof(double)); + if(args->num_opt == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_kill_arg(args); + free(hash_list); + return NULL; + } + args->num_opt[args->count++] = strtof(str, NULL); + } + } + break; + } + + /*--------------------------------------------------------*\ + ! This type of argument/option accepts four additional nu- ! + ! merical values that are passed to parser as a non-hyphen-! + ! ated command-line arguments. ! + \*--------------------------------------------------------*/ + case 0x000000017C82A8C7: + { + /*--------------------------------------------------------*\ + ! Store the hash identifier in the linked list node. ! + \*--------------------------------------------------------*/ + args->hash = hash_list[2 * l]; + + /*--------------------------------------------------------*\ + ! Loop through the next four command-line arguments, check ! + ! that they are non-hyphenated and, if true, store their ! + ! numerical values handle in the list node. ! + \*--------------------------------------------------------*/ + for(j = i + 1; j < argc && (get_opt(argv[j]) == NULL); ++j) + { + /*--------------------------------------------------------*\ + ! Allocate the num_opt array for 4 real values. ! + \*--------------------------------------------------------*/ + if(args->num_opt == NULL) + { + args->num_opt = calloc(4, sizeof(double)); + if(args->num_opt == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_kill_arg(args); + free(hash_list); + return NULL; + } + args->count = 0x04; + } + + /*--------------------------------------------------------*\ + ! Save the memory handle for the next argument in a tempo- ! + ! rary variable and tokenize the string according to the ! + ! specified delimiters. ! + \*--------------------------------------------------------*/ + str = argv[j]; + token = strtok_r(str, ":=\t, ", &ptr); + + /*--------------------------------------------------------*\ + ! Check if a valid token has been generated for the first ! + ! spatial direction. If true, save the numerical value, ! + ! set the dimension flag and generate the next token. ! + \*--------------------------------------------------------*/ + if(token && ((strchr(token, 'x') != NULL) || + (strchr(token, 'X') != NULL))) + { + token = strtok_r(NULL, ":=\t, ", &ptr); + if(token != NULL) + { + args->num_opt[0] = strtof(token, NULL); + args->dim |= 0x01; + } + token = strtok_r(NULL, ":=\t, ", &ptr); + } + + /*--------------------------------------------------------*\ + ! Check if a valid token has been generated for the second ! + ! spatial direction. If true, save the numerical value, ! + ! set the dimension flag and generate the next token. ! + \*--------------------------------------------------------*/ + if(token && ((strchr(token, 'y') != NULL) || + (strchr(token, 'Y') != NULL))) + { + token = strtok_r(NULL, ":=\t, ", &ptr); + if(token != NULL) + { + args->num_opt[1] = strtof(token, NULL); + args->dim |= 0x02; + } + token = strtok_r(NULL, ":=\t, ", &ptr); + } + + /*--------------------------------------------------------*\ + ! Check if a valid token has been generated for the third ! + ! spatial direction. If true, save the numerical value, ! + ! set the dimension flag and generate the next token. ! + \*--------------------------------------------------------*/ + if(token && ((strchr(token, 'z') != NULL) || + (strchr(token, 'Z') != NULL))) + { + token = strtok_r(NULL, ":=\t, ", &ptr); + if(token != NULL) + { + args->num_opt[2] = strtof(token, NULL); + args->dim |= 0x04; + } + token = strtok_r(NULL, ":=\t, ", &ptr); + } + + /*--------------------------------------------------------*\ + ! Check if a valid token has been generated for the first ! + ! temporal direction. If true, save the numerical value, ! + ! set the dimension flag and generate the next token. ! + \*--------------------------------------------------------*/ + if(token && ((strchr(token, 't') != NULL) || + (strchr(token, 'T') != NULL))) + { + token = strtok_r(NULL, ":=\t, ", &ptr); + if(token != NULL) + { + args->num_opt[3] = strtof(token, NULL); + args->dim |= 0x08; + } + token = strtok_r(NULL, ":=\t, ", &ptr); + } + } + break; + } + + /*--------------------------------------------------------*\ + ! This type of argument/option accepts one ore more numeri-! + ! cal values that are passed to parser as a non-hyphenated ! + ! command-line arguments. ! + \*--------------------------------------------------------*/ + case 0x000000017C82A8BF: + { + /*--------------------------------------------------------*\ + ! Store the hash identifier in the linked list node. ! + \*--------------------------------------------------------*/ + args->hash = hash_list[2 * l]; + + /*--------------------------------------------------------*\ + ! Loop through the next command-line arguments that are ! + ! non-hyphenated and store their numerical values handle ! + ! in the list node. ! + \*--------------------------------------------------------*/ + for(j = i + 1; j < argc && (get_opt(argv[j]) == NULL); ++j) + { + /*--------------------------------------------------------*\ + ! Save the memory handle for the next argument in a tempo- ! + ! rary variable and tokenize the string according to the ! + ! specified delimiters. ! + \*--------------------------------------------------------*/ + str = argv[j]; + token = strtok_r(str, ", ", &ptr); + + /*--------------------------------------------------------*\ + ! Check if a valid token has been generated. If true, re- ! + ! size the num_opt array, save the numerical value, and ! + ! generate the next token. ! + \*--------------------------------------------------------*/ + for(; (token != NULL); token = strtok_r(NULL, ", ", &ptr)) + { + if(token != NULL) + { + if(strtof(token, NULL) > 0.0f) + { + args->num_opt = realloc(args->num_opt, (args->count + 1) * sizeof(double)); + if(args->num_opt == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_kill_arg(args); + free(hash_list); + return NULL; + } + args->num_opt[args->count++] = strtof(token, NULL); + } + } + } + } + break; + } + + default: + { + continue; + } + } + /*--------------------------------------------------------*\ + ! Allocate and initialize the next linked list node. ! + \*--------------------------------------------------------*/ + args->next = calloc(1, sizeof(bwc_cmdl_arg_node)); + if(args->next == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_kill_arg(args); + free(hash_list); + return NULL; + } + args->next->root = args->root; + args = args->next; + } + } + } + } + /*--------------------------------------------------------*\ + ! Free the command line argument hash list and return the ! + ! linked list to the function caller. ! + \*--------------------------------------------------------*/ + free(hash_list); + return args; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to parse the util_arg_node linked list and, if it is pre- ! +! sent in linked list, return the memory handle to the bwc argument/option short- ! +! /long-name supplied by the function. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! args util_arg_node* - Arguments/options linked list ! +! for the bwc command-line tool. ! +! ! +! str char* - Long-/short-name of a bwc com- ! +! mand-line argument or option. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! util_arg_nodes* - Memory handle bwc argument ! +! linked list node. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 24.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static bwc_cmdl_arg_node* +retrieve_arg(bwc_cmdl_arg_node *const args, + char* name) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64_t arg_hash; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_cmdl_arg_node *temp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(args); + assert(name); + + /*--------------------------------------------------------*\ + ! Generate a hash from the argument/option name and save ! + ! the root node memory address in a temporary variable. ! + \*--------------------------------------------------------*/ + arg_hash = hash(name); + temp = args->root; + + /*--------------------------------------------------------*\ + ! Advance through the linked list until the argument/op- ! + ! tion, corresponding to the supplied name, has been found ! + ! or the end of the list has been reached. ! + \*--------------------------------------------------------*/ + while(temp->hash != arg_hash && temp->next != NULL) + temp = temp->next; + + /*--------------------------------------------------------*\ + ! If found, return the memory handle to the argument/op- ! + ! option to the function caller. ! + \*--------------------------------------------------------*/ + if((temp->next != NULL) && (temp->hash == arg_hash)) + return temp; + else + return NULL; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function prints the help page to the standard output. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! - - - ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 14.05.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 03.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static void +print_help(void) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint16_t i; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char *buf; + + /*--------------------------------------------------------*\ + ! Write the head of the help message to the standard out- ! + ! put. ! + \*--------------------------------------------------------*/ + printf("Usage: bwc [arguments] [file] [options] (De)compress a specified [file] using [options]. \n"\ + " \n"\ + "e.g.: bwc -c -i [input] -o [output] [options] Compress an [input] file with the specified [op- \n"\ + " tions] and save the compressed bitstream in the \n"\ + " [output] file. \n"\ + " \n"\ + "e.g.: bwc -c [input] [options] Compress an [input] file with the specified [op- \n"\ + " tions] and save the compressed bitstream. \n"\ + " \n"\ + "e.g.: bwc -d -i [input] -o [output] [options] Decompress an [input] file with the specified [op-\n"\ + " tions] and save the decompressed bitstream in the \n"\ + " [output] file. \n"\ + " \n"\ + "e.g.: bwc -d [input] [options] Decompress an [input] file with the specified [op-\n"\ + " tions] and save the decompressed bitstream. \n"\ + " \n"\ + "e.g.: bwc -al -i [input] -ref [reference] Evaluate the Peak-Signal-to-Noise-Ratio of the \n"\ + " [input] file with regards to the [reference] file \n"\ + " and print the result to the standard output. \n"\ + " \n"\ + "e.g.: bwc -if -i [input] Print the header information of the compressed \n"\ + " [input] file to the standard output. \n"\ + " \n"\ + " \n"\ + "Arguments: \n"\ + " \n"\ + " [Type] [Usage] [Description] \n"\ + " \n"); + + /*--------------------------------------------------------*\ + ! Loop through the command line arguments list and write ! + ! the short and long name, usage example and description ! + ! for all mandatory (arg) command line arguments to stdout.! + \*--------------------------------------------------------*/ + for(i = 0; strcmp(CMDL_ARGS[i].arg_type, "end"); ++i) + { + if(strcmp(CMDL_ARGS[i].arg_type, "arg") == 0 && CMDL_ARGS[i].active) + { + printf(" -%s,\t", CMDL_ARGS[i].arg_short); + printf("--%-24s", CMDL_ARGS[i].arg_long); + printf("%-24s", CMDL_ARGS[i].usage); + printf("%.50s\n", CMDL_ARGS[i].definition); + + for(buf = CMDL_ARGS[i].definition + 50; strcmp(buf, ""); buf += 50) + { + printf("%58s%.50s\n", "", buf); + } + + printf("\n"); + } + } + + /*--------------------------------------------------------*\ + ! Write the head of the optional arguments list to the ! + ! standard output. ! + \*--------------------------------------------------------*/ + printf("Options: \n"\ + " \n"\ + " [Type] [Usage] [Description] \n"\ + " \n"); + + /*--------------------------------------------------------*\ + ! Loop through the command line arguments list and write ! + ! the short and long name, usage example and description ! + ! for all optional (arg) command line arguments to stdout. ! + \*--------------------------------------------------------*/ + for(i = 0; strcmp(CMDL_ARGS[i].arg_type, "end"); ++i) + { + if(strcmp(CMDL_ARGS[i].arg_type, "opt") == 0 && CMDL_ARGS[i].active) + { + printf(" -%s,\t", CMDL_ARGS[i].arg_short); + printf("--%-24s", CMDL_ARGS[i].arg_long); + printf("%-24s", CMDL_ARGS[i].usage); + printf("%.50s\n", CMDL_ARGS[i].definition); + + for(buf = CMDL_ARGS[i].definition+50; strcmp(buf, ""); buf += 50) + { + printf("%58s%.50s\n", "", buf); + } + + printf("\n"); + } + } +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function prints the header information of a compressed dataset to the ! +! standard output. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! args util_arg_node* - Arguments/options linked list ! +! for the bwc command-line tool. ! +! ! +! name char* - Long-/short-name of a bwc com- ! +! mand-line argument or option. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 12.09.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 17.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static void +output_info(bwc_cmdl_arg_node *const args, + char* name) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64_t data_points; + + uint64_t Ld; + uint32_t Ls; + uint16_t Lh; + + uint32_t t; + uint8_t l, p; + + uint16_t marker; + uint8_t index; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + bwc_float minVal, maxVal; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char *buff; + uchar status; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_field *field; + bwc_data *data; + + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + bwc_param_ctrl *param_ctrl; + bwc_param_inf *param_info; + + bwc_cmdl_arg_node *temp; + + bwc_stream *stream; + struct stat buf; + + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(args); + + /*--------------------------------------------------------*\ + ! Retrieve the file argument from the linked list and con- ! + ! firm that only one file has been specified and that it ! + ! is a regular file. If true, open the file for reading. ! + \*--------------------------------------------------------*/ + temp = retrieve_arg(args, name); + if((temp == NULL) || + (temp->lit_opt == NULL) || + (temp->lit_opt[0] == NULL)) + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: File |\n"\ + "| |\n"\ + "| No File has been specified. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return; + } + + if(temp->count > 1) + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: File |\n"\ + "| |\n"\ + "| More than one file has been specified. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return; + } + + stat(temp->lit_opt[0], &buf); + if(!S_ISREG(buf.st_mode)) + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: file |\n"\ + "| |\n"\ + "| The specified input is not a regular file. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return; + } + + fp = fopen(temp->lit_opt[0], "rb"); + if(fp == NULL) + { + // error opening file + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Could not open or read %-25s|\n"\ + "o##########################################################o\n", temp->lit_opt[0]); + return; + } + + /*--------------------------------------------------------*\ + ! Initialize the codestream status and reading index var- ! + ! iables and parse the codestream to evaluate the size of ! + ! the main header. ! + \*--------------------------------------------------------*/ + status = CODESTREAM_OK; + index = 0; + + while(status == 0) + { + Ld = fread(&marker, sizeof(uint16_t), 1, fp); + endian_conversion(&marker, 2); + if((Ld != 1) || (marker < 0xFF00)) + { + // Invalid Codestream + fprintf(stderr, CSTERROR); + fclose(fp); + return; + } + + switch(marker) + { + case SOC: + { + break; + } + + case COM: + case SGC: + case SGI: + default: + { + if(fread(&Lh, sizeof(uint16_t), 1, fp) != 1) + { + // Invalid Codestream + fprintf(stderr, CSTERROR); + fclose(fp); + return; + } + + endian_conversion(&Lh, 2); + fseek(fp, Lh - 2, SEEK_CUR); + + break; + } + + case SAX: + { + if(fread(&Ls, sizeof(uint32_t), 1, fp) != 1) + { + // Invalid Codestream + fprintf(stderr, CSTERROR); + fclose(fp); + return; + } + + endian_conversion(&Ls, 4); + fseek(fp, Ls - 4, SEEK_CUR); + + break; + } + + case EOH: + { + if(fread(&Lh, sizeof(uint16_t), 1, fp) != 1) + { + // Invalid Codestream + fprintf(stderr, CSTERROR); + fclose(fp); + return; + } + + endian_conversion(&Lh, 2); + fseek(fp, Lh - 2, SEEK_CUR); + + status |= CODESTREAM_READ; + break; + } + } + index++; + } + + /*--------------------------------------------------------*\ + ! Determine the size of the main header present in the bwc ! + ! codestream and allocate the data structure, packed code- ! + ! stream sub-structure and its memory block. ! + \*--------------------------------------------------------*/ + Ld = ftell(fp); + fseek(fp, 0L, SEEK_SET); + + data = calloc(1, sizeof(bwc_data)); + if(data == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + fclose(fp); + return; + } + + data->codestream.data = calloc(1, sizeof(bwc_packed_stream)); + if(data->codestream.data == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(data); + fclose(fp); + return; + } + + data->codestream.data->memory = calloc(Ld, sizeof(uchar)); + if(data->codestream.data->memory == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(data); + fclose(fp); + return; + } + + /*--------------------------------------------------------*\ + ! Read the main header from the packed codestream of the ! + ! user specified bcw file and set up the data structure. ! + \*--------------------------------------------------------*/ + if(fread(data->codestream.data->memory, sizeof(uchar), Ld, fp) != Ld) + { + // invalid read + fprintf(stderr, RDERROR); + bwc_free_data(data); + fclose(fp); + return; + } + + data->codestream.data->access = data->codestream.data->memory; + data->codestream.data->size = Ld; + data->codestream.data->position = 0; + + /*--------------------------------------------------------*\ + ! Initialize the bitstream, parse the main header and set ! + ! up the field structure for the current dataset. ! + \*--------------------------------------------------------*/ + stream = calloc(1, sizeof(bwc_stream)); + if(stream == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return; + } + + stream->memory = data->codestream.data->memory; + + stream->t = 0; + stream->Lmax = data->codestream.data->size; + stream->size_incr = (uint64)(stream->Lmax / 2); + + field = bwc_parse_main_header(data, stream); + if(field == NULL) + { + bwc_free_data(data); + free(stream); + fclose(fp); + return; + } + control = &field->control; + info = field->info; + + free(stream); + + /*--------------------------------------------------------*\ + ! Write the help message to the standard output. ! + \*--------------------------------------------------------*/ + printf("/================================================================================\\\n"\ + "| |\n"\ + "| .:-------------: .:-------------: |\n"\ + "| .+++++++++++++++= :+++++++++++++++- |\n"\ + "| :+++. -++= -++= |\n"\ + "| :+++. -++= -++= |\n"\ + "| -++++++++++++++= -++= -++= |\n"\ + "| .=++---------=++= -++= -++= |\n"\ + "| :+++ :++= -++= -++= |\n"\ + "| .+++=--------=+++---=+++---=+++------------: |\n"\ + "| -=++++++++++++++++++++++++++++++++++++++++- |\n"\ + "| |\n"\ + "|-------------------------------General Information------------------------------|\n"\ + "| |\n"); + + /*--------------------------------------------------------*\ + ! Print the original file size and format. ! + \*--------------------------------------------------------*/ + fseek(fp, 0L, SEEK_END); + Ld = ftell(fp); + buff = get_size(Ld); + fclose(fp); + + printf("| Original size: %42s |\n"\ + "| Original file format: %42s |\n"\ + "|%80s|\n", buff, info->f_ext, " "); + + free(buff); + + /*--------------------------------------------------------*\ + ! Print the file size and compression ratio. ! + \*--------------------------------------------------------*/ + data_points = (uint64)info->nX * info->nY * info->nZ * + info->nTS * info->nPar; + buff = get_size(data_points * 8); + + printf("| Size on Disk: %42s |\n"\ + "| Comp. Ratio: %42.2f |\n"\ + "|%80s|\n", buff, ((double)data_points * 8.0f/Ld), " "); + + free(buff); + + /*--------------------------------------------------------*\ + ! Print the number of datapoints. ! + \*--------------------------------------------------------*/ + buff = get_digit_sep(data_points); + printf("| Number of Datapoints: %42s |\n"\ + "|%80s|\n", buff, " "); + free(buff); + + buff = get_digit_sep(info->nX); + printf("| -1st Dim.: %42s |\n", buff); + free(buff); + + buff = get_digit_sep(info->nY); + printf("| -2nd Dim.: %42s |\n", buff); + free(buff); + + buff = get_digit_sep(info->nZ); + printf("| -3nd Dim.: %42s |\n", buff); + free(buff); + + buff = get_digit_sep(info->nTS); + printf("| -Time Steps: %42s |\n"\ + "| -No. Params: %42d |\n"\ + "|%80s|\n", buff, info->nPar, " "); + free(buff); + + /*--------------------------------------------------------*\ + ! Print the numerical Datapoints. ! + \*--------------------------------------------------------*/ + printf("|------------------------------Numerical Parameters------------------------------|\n"\ + "| |\n"); + + for(p = 0; p < info->nPar; ++p) + { + param_ctrl = &field->tile[0].parameter[p].control; + param_info = &field->tile[0].parameter[p].info; + + minVal = param_info->parameter_min; + maxVal = param_info->parameter_max; + + for(t = 0; t <= control->nTiles; ++t) + { + minVal = MIN(minVal, param_info->parameter_min); + maxVal = MIN(maxVal, param_info->parameter_max); + } + + buff = param_info->name + strlen(param_info->name) - 1; + while(buff > param_info->name && isspace((unsigned char)*buff)) buff--; + buff[1] = '\0'; + + printf("| Name: %55s |\n"\ + "| Minimum value: %55.2e |\n"\ + "| Maximum value: %55.2e |\n"\ + "| |\n"\ + "| 1.D | 2.D | 3.D | TS |\n"\ + "| Sampling factor: %2d | %2d | %2d | %2d |\n"\ + "| ........................................................................ |\n" + "|%80s|\n", param_info->name, + minVal, + maxVal, + param_ctrl->sampX, + param_ctrl->sampY, + param_ctrl->sampZ, + param_ctrl->sampTS, " "); + } + + /*--------------------------------------------------------*\ + ! Print the quality layers. ! + \*--------------------------------------------------------*/ + printf("|---------------------------------Quality Layers---------------------------------|\n"\ + "| |\n"); + + for(l = 0; l < control->nLayers; ++l) + { + buff = get_size(data_points * control->bitrate[l]); + + printf("| |\n"\ + "| Quality Layer Nr. %d: %40.2f Bpd |\n"\ + "| %44s |\n", l + 1, control->bitrate[l], buff); + free(buff); + } + + printf("| |\n"\ + "\\--------------------------------------------------------------------------------/\n"); + + /*--------------------------------------------------------*\ + ! Free the field structure. ! + \*--------------------------------------------------------*/ + bwc_kill_compression(field); + bwc_free_data(data); +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function opens a bwc file, checks it for its validity and loads its con- ! +! tent into a properly set up bwc_data structure. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! filename char* - Name of the bwc file that is ! +! to be opened and read. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! bwc_data* - Structure containing a code- ! +! stream/numerical dataset. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! 17.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static bwc_data* +read_bwc(char *const filename) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64_t Lfield; + uint16_t root; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_data *file; + + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(filename); + + /*--------------------------------------------------------*\ + ! Open the specified file for reading and, if succesful, ! + ! determine the size of the codestream. If the file could ! + ! not be opened, print an error message to stderr and exit.! + \*--------------------------------------------------------*/ + fp = fopen(filename, "rb"); + if(fp != NULL) + { + root = ftell(fp); + fseek(fp, 0L, SEEK_END); + Lfield = ftell(fp) - root; + fseek(fp, root, SEEK_SET); + } + else + { + // error opening file + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Could not open or read %-25s|\n"\ + "o##########################################################o\n", filename); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Allocate the data and packed codestream structure as ! + ! well as the memory block that will hold the codestream. ! + \*--------------------------------------------------------*/ + file = calloc(1, sizeof(bwc_data)); + if(file == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + fclose(fp); + return NULL; + } + + file->codestream.data = calloc(1, sizeof(bwc_packed_stream)); + if(file->codestream.data == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + fclose(fp); + return NULL; + } + + file->codestream.data->memory = calloc(Lfield, sizeof(uchar)); + if(file->codestream.data->memory == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + fclose(fp); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Read the compressed bitstream from the file and, if suc- ! + ! essfull, properly set up the packed codestream and re- ! + ! turn the bwc_data structre to the function caller. ! + \*--------------------------------------------------------*/ + if(fread(file->codestream.data->memory, sizeof(uchar), Lfield, fp) != Lfield) + { + // invalid read + fprintf(stderr, RDERROR); + bwc_free_data(file); + fclose(fp); + return NULL; + } + + file->codestream.data->access = file->codestream.data->memory; + file->codestream.data->size = Lfield; + file->codestream.data->position = 0; + + fclose(fp); + return file; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function opens a bwc file, checks it for its validity and writes the code- ! +! stream, provided by the function caller, to the file. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! filename char* - Name of the bwc file that is ! +! to be created. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! 17.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static uchar +write_bwc(bwc_data *const data, + char *const filename) +{ + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(data); + assert(filename); + + /*--------------------------------------------------------*\ + ! Open the specified file for writing If the file could ! + ! not be opened, print an error message to stderr and exit.! + \*--------------------------------------------------------*/ + fp = fopen(filename, "wb"); + if(fp == NULL) + { + // error opening file + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Could not open %-33s|\n"\ + "o##########################################################o\n", filename); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Write the compressed codestream to file and, if success- ! + ! ful, close the file ptr and return to the fun. caller. ! + \*--------------------------------------------------------*/ + if(fwrite(data->codestream.data->memory, sizeof(uchar), data->codestream.data->size, fp) != + data->codestream.data->size) + { + // error opening file + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Could not write to %-29s|\n"\ + "o##########################################################o\n", filename); + fclose(fp); + return EXIT_FAILURE; + } + + fclose(fp); + return EXIT_SUCCESS; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is a wrapper that is used to invoke the appropriate read func- ! +! tion according to the file extension of the user supplied filename. The data- ! +! set is stored in the bwc_data structure and passed onto the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! args util_arg_node* - Arguments/options linked list ! +! for the bwc command-line tool. ! +! ! +! str char* - Long-/short-name of a bwc com- ! +! mand-line argument or option. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! bwc_data* - Structure containing a code- ! +! stream/numerical dataset. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 14.05.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 03.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static bwc_data* +read_file(bwc_cmdl_arg_node *const args, + char* name) +{ + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char *str; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_cmdl_arg_node *temp; + bwc_data *file; + struct stat buf; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(args); + assert(name); + + /*--------------------------------------------------------*\ + ! Retrieve the file argument from the linked list and con- ! + ! firm that only one file has been specified and that it ! + ! is a regular file. ! + \*--------------------------------------------------------*/ + temp = retrieve_arg(args, name); + if((temp == NULL) || + (temp->lit_opt == NULL) || + (temp->lit_opt[0] == NULL)) + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: File |\n"\ + "| |\n"\ + "| No File has been specified. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return NULL; + } + + if(temp->count > 1) + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: File |\n"\ + "| |\n"\ + "| More than one file has been specified. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return NULL; + } + + stat(temp->lit_opt[0], &buf); + if(!S_ISREG(buf.st_mode)) + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: file |\n"\ + "| |\n"\ + "| The specified input is not a regular file. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Extract the file extension from the input string and use ! + ! it to invoke the appropriate read function. ! + \*--------------------------------------------------------*/ + str = strrchr(temp->lit_opt[0], '.'); + switch(hash(str)) + { + case 0x000000017C4DC25C: + { + file = read_eas3(temp->lit_opt[0]); + if(file == NULL) + { + return NULL; + } + + return file; + } + + case 0x000000017C4DAF1D: + { + file = read_bwc(temp->lit_opt[0]); + if(file == NULL) + { + return NULL; + } + + return file; + } + + default: + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: File |\n"\ + "| |\n"\ + "| The format of the specified file is currently |\n"\ + "| not supported. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return NULL; + } + } +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is a wrapper that is used to invoke the appropriate write func- ! +! tion according to the file extension supplied by the user or codestream. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! args util_arg_node* - Arguments/options linked list ! +! for the bwc command-line tool. ! +! ! +! str char* - Long-/short-name of a bwc com- ! +! mand-line argument or option. ! +! ! +! data bwc_data* - Structure containing a code- ! +! stream/numerical dataset. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 14.05.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 17.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static uchar +write_file(bwc_cmdl_arg_node *const args, + bwc_data *const data, + char* name) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + uint64_t ext_hash; + uint16_t new_len; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_cmdl_arg_node *temp; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char *str; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(data); + assert(args); + assert(name); + + /*--------------------------------------------------------*\ + ! Retrieve the file argument from the linked list and con- ! + ! firm that only one file has been specified. ! + \*--------------------------------------------------------*/ + temp = retrieve_arg(args, name); + if((temp == NULL) || + (temp->lit_opt == NULL) || + (temp->lit_opt[0] == NULL)) + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: File |\n"\ + "| |\n"\ + "| No File has been specified. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return EXIT_FAILURE; + } + + if(temp->count > 1) + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: File |\n"\ + "| |\n"\ + "| More than one file has been specified. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! If the output is a packed codestream, replace the user ! + ! supplied with the propper '.bwc' file extension to en- ! + ! sure uniformity. ! + \*--------------------------------------------------------*/ + if((retrieve_arg(args, "compress") != NULL) && (data->codestream.data != NULL)) + { + /*--------------------------------------------------------*\ + ! Extract the filename in the output argument, remove its ! + ! file extension and calculate the new string length with ! + ! the '.bwc' extension. ! + \*--------------------------------------------------------*/ + str = strrchr(temp->lit_opt[0], '.'); + str[1] = '\0'; + + new_len = (strlen(temp->lit_opt[0]) + 4) * sizeof(char); + + /*--------------------------------------------------------*\ + ! Resize the filename string in the output argument and ! + ! ammend the new file extension. ! + \*--------------------------------------------------------*/ + str = calloc(new_len, sizeof(char)); + if(str == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + sprintf(str, "%s%s", temp->lit_opt[0],"bwc"); + + /*--------------------------------------------------------*\ + ! Write the codestream to the filesystem. ! + \*--------------------------------------------------------*/ + if(write_bwc(data, str) == EXIT_FAILURE) + { + free(str); + return EXIT_FAILURE; + } + } + /*--------------------------------------------------------*\ + ! If the output is a numerical dataset, generate the ap- ! + ! propriate filename and write the information to file. ! + \*--------------------------------------------------------*/ + else if((retrieve_arg(args, "decompress") != NULL) && ((data->field.d != NULL) || + (data->field.f != NULL))) + { + /*--------------------------------------------------------*\ + ! If no output file has been specified, assemble the file- ! + ! name using the input name and file extension assoc. with ! + ! the codestream. Generate the ext. hash accordingly. ! + \*--------------------------------------------------------*/ + if(strcmp(name, "decompress") == 0) + { + ext_hash = hash(data->info.f_ext); + str = strrchr(temp->lit_opt[0], '.'); + str[0] = '\0'; + + new_len = (strlen(temp->lit_opt[0]) + + strlen(data->info.f_ext) + 7) * sizeof(char); + + str = calloc(new_len, sizeof(char)); + if(str == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + sprintf(str, "%s%s%s", temp->lit_opt[0], "_d.", data->info.f_ext); + } + /*--------------------------------------------------------*\ + ! If an output file has been specified, extract the file ! + ! extension, evaluate the corresponding hash and check ! + ! that the codestream supports the file format. ! + \*--------------------------------------------------------*/ + else + { + ext_hash = hash(strrchr(temp->lit_opt[0], '.')); + if(ext_hash != hash(data->info.f_ext)) + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Incompatible File Format |\n"\ + "| |\n"\ + "| The format of the specified file is incom- |\n"\ + "| patible with the information stored in the |\n"\ + "| codestream. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return EXIT_FAILURE; + } + + str = calloc(strlen(temp->lit_opt[0]) + 1, sizeof(char)); + if(str == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + strcpy(str, temp->lit_opt[0]); + } + + /*--------------------------------------------------------*\ + ! Use the extension hash to invoke the appropriate write ! + ! function. ! + \*--------------------------------------------------------*/ + switch (ext_hash) + { + case 0X0000000000B87A592: + { + if(write_eas3(data, str) == EXIT_FAILURE) + { + free(str); + return EXIT_FAILURE; + } + break; + } + + default: + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: File |\n"\ + "| |\n"\ + "| The format of the specified file is currently |\n"\ + "| not supported. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + free(str); + return EXIT_FAILURE; + } + } + } + /*--------------------------------------------------------*\ + ! If no apporprite in- or output argument has been speci- ! + ! fied return an error handle to the function caller. ! + \*--------------------------------------------------------*/ + else + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Data |\n"\ + "| |\n"\ + "| Output can not be generated because no valid |\n"\ + "| data has been specified. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return EXIT_FAILURE; + } + + free(str); + return EXIT_SUCCESS; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! | | ! +! This function calculates the Peak-Signal-to-Noise-Ratio of a compressed file ! +! in relation to the original reference file. The mean square error and peak ! +! signal to noise ratio are written to the standard output. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! args util_arg_node* - Arguments/options linked list ! +! for the bwc command-line tool. ! +! ! +! name char* - Long-/short-name of a bwc com- ! +! mand-line argument or option. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 12.09.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 17.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static uchar +output_analysis(bwc_cmdl_arg_node *const args) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64_t size; + uint64_t i; + + uint8_t p; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + double MSE, PSNR; + double peakVal; + double sum; + + double *dOrig, *dRef; + float *fOrig, *fRef; + + bwc_float minVal, maxVal; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_data *file, *ref; + + bwc_cmd_opts_ll *param; + + /*--------------------------------------------------------*\ + ! Load the input and reference files into the appropriate ! + ! file structures. ! + \*--------------------------------------------------------*/ + file = read_file(args, "input"); + if(file == NULL) + { + return EXIT_FAILURE; + } + + ref = read_file(args, "reference"); + if(ref == NULL) + { + bwc_free_data(file); + return EXIT_FAILURE; + } + + dOrig = file->field.d; + dRef = ref->field.d; + + fOrig = file->field.f; + fRef = ref->field.f; + + if(file->info.nX == ref->info.nX && + file->info.nY == ref->info.nY && + file->info.nZ == ref->info.nZ && + file->info.nTS == ref->info.nTS && + file->info.nPar == ref->info.nPar) + { + size = (uint64_t)ref->info.nX * ref->info.nY * + ref->info.nZ * ref->info.nTS; + + peakVal = -1.7976931348623157e+308; + PSNR = + MSE = 0; + + if(ref->info.parameter) + { + param = ref->info.parameter->root; + p = 0; + while(param != NULL) + { + minVal = 1.7976931348623157e+308; + maxVal = -1.7976931348623157e+308; + + if(param->precision == 8) + { + for(i = 0; i < size; ++i) + { + minVal = MIN(minVal, (double)dRef[i + p * size]); + maxVal = MAX(maxVal, (double)dRef[i + p * size]); + + sum = ((double)dRef[i + p * size] - (double)dOrig[i + p * size]); + + MSE += sum * sum; + } + } + else if(param->precision == 4) + { + for(i = 0; i < size; ++i) + { + minVal = MIN(minVal, (double)fRef[i + p * size]); + maxVal = MAX(maxVal, (double)fRef[i + p * size]); + + sum = ((double)fRef[i + p * size] - (double)fOrig[i + p * size]); + + MSE += sum * sum; + } + } + peakVal = MAX(peakVal, maxVal - minVal); + param = param -> next; + p++; + } + } + + MSE /= (double)size * ref->info.nPar; + PSNR = 20 * log10(peakVal/(2 * sqrt(MSE))); + + printf("==============================================================\n"); + printf(" Mean Square Error: %*.2f\n", 22, MSE); + printf(" Peak Signal-to-Noise Ratio: %*.2f\n", 22, PSNR); + printf("==============================================================\n"); + + } + /*--------------------------------------------------------*\ + ! Load the input and reference files into the appropriate ! + ! file structures. ! + \*--------------------------------------------------------*/ + bwc_free_data(file); + bwc_free_data(ref); + + return EXIT_SUCCESS; +} + +/**********************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function provides a command-line interface for the BigWhoop compression ! +! library. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! argc int - Number of strings pointed to ! +! by argv. ! +! ! +! argv char** - Array of arguments. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! int - Return value signaling a normal ! +! or abnormal process exit. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 17.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 15.05.2021 Patrick Vogler B880CA2 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +int +main(int argc, + char *argv[]) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64_t size=0; + uint64_t i; + uint8_t error_handle; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char *csSize = NULL; + char *fdSize = NULL; + char buff[200]; + char rate[10]; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + double comp_ratio; + double bpd; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_field *field = NULL; + bwc_data *file = NULL; + + bwc_gl_ctrl *control; + + bwc_dwt_filter filter[4]; + bwc_cmdl_arg_node *args, *temp; + + bwc_cmd_opts_ll *param; + + /*--------------------------------------------------------*\ + ! Initialize the field and args structures for proper er- ! + ! ror handling, as well as the error handle itself. ! + \*--------------------------------------------------------*/ + field = NULL; + args = NULL; + + error_handle = EXIT_SUCCESS; + + /*--------------------------------------------------------*\ + ! Assemble the arg. linked list using the command-line ar- ! + ! guments passed by the function caller. ! + \*--------------------------------------------------------*/ + args = parse_arguments(argc, argv); + if(args == NULL) + { + error_handle = EXIT_FAILURE; + print_help(); + goto OUT; + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + if(retrieve_arg(args, "compress") != NULL) + { + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + if(retrieve_arg(args, "input")) + file = read_file(args, "input"); + else + file = read_file(args, "compress"); + + if(file == NULL) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + field = bwc_initialize_field(file); + if(field == NULL) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + control = &field->control; + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + temp = retrieve_arg(args, "q_format_range"); + if((temp != NULL) && (temp->count == 1)) + { + bwc_set_qm(field, (uint8_t)temp->num_opt[0]); + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + temp = retrieve_arg(args, "wavelet_kernels"); + if((temp != NULL) && (temp->count == 4) && (temp->dim != 0x00)) + { + for(i = 0; i < temp->count; ++i) + { + switch(hash(temp->lit_opt[i])) + { + case 0x000000000B87CF64: + { + filter[i] = bwc_dwt_9_7; + break; + } + case 0x00000652AB15772A: + { + filter[i] = bwc_dwt_5_3; + break; + } + case 0x000000017C858EFF: + { + filter[i] = bwc_dwt_5_3; + break; + } + default: + { + filter[i] = bwc_dwt_9_7; + break; + } + } + } + bwc_set_kernels(field, filter[0], filter[1], + filter[2], filter[3]); + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + temp = retrieve_arg(args, "decomposition_levels"); + if((temp != NULL) && (temp->count == 4) && (temp->dim != 0x00)) + { + bwc_set_decomp(field, (uint8_t)temp->num_opt[0], (uint8_t)temp->num_opt[1], + (uint8_t)temp->num_opt[2], (uint8_t)temp->num_opt[3]); + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + temp = retrieve_arg(args, "tile_size"); + if((temp != NULL) && (temp->count == 4) && (temp->dim != 0x00)) + { + bwc_set_tiles(field, (uint64_t)temp->num_opt[0], (uint64_t)temp->num_opt[1], + (uint64_t)temp->num_opt[2], (uint64_t)temp->num_opt[3], bwc_tile_sizeof); + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + temp = retrieve_arg(args, "precinct_size"); + if((temp != NULL) && (temp->count == 4) && (temp->dim != 0x00)) + { + bwc_set_precincts(field, (uint8_t)temp->num_opt[0], (uint8_t)temp->num_opt[1], + (uint8_t)temp->num_opt[2], (uint8_t)temp->num_opt[3]); + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + temp = retrieve_arg(args, "codeblock_size"); + if((temp != NULL) && (temp->count == 4) && (temp->dim != 0x00)) + { + bwc_set_codeblocks(field, (uint8_t)temp->num_opt[0], (uint8_t)temp->num_opt[1], + (uint8_t)temp->num_opt[2], (uint8_t)temp->num_opt[3]); + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + temp = retrieve_arg(args, "quantisation_style"); + if((temp != NULL) && (temp->count == 1)) + { + if(strcmp(temp->lit_opt[0], "NONE")) + bwc_set_quantization_style(field, bwc_qt_none); + else + bwc_set_quantization_style(field, bwc_qt_derived); + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + temp = retrieve_arg(args, "quantisation_step_size"); + if((temp != NULL) && (temp->count == 1)) + { + bwc_set_quantization_step_size(field, temp->num_opt[0]); + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + memset(buff, 0, 200 * sizeof(char)); + + temp = retrieve_arg(args, "bitrate"); + if((temp != NULL) && (temp->count > 0)) + { + for(i = 0; i < temp->count && strlen(buff) < 192; ++i) + { + sprintf(rate, "%05.3f,", temp->num_opt[i]); + strcat(buff, rate); + } + buff[strlen(buff) - 1] = '0'; + } + + temp = retrieve_arg(args, "compression_ratio"); + if((temp != NULL) && (temp->count == 1)) + { + sprintf(buff, "%05.3f", ((double)PREC_BIT + 1.0f)/temp->num_opt[0]); + } + + if(strlen(buff) == 0) + { + sprintf(buff, "-"); + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + temp = retrieve_arg(args, "number_of_threads"); + if((temp != NULL) && (temp->count == 1)) + { + bwc_set_nThreads(field, (uint8_t)temp->num_opt[0]); + } + #endif + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + if(retrieve_arg(args, "error_resilience")) + { + bwc_set_error_resilience(field); + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + if(bwc_create_compression(field, buff)) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + + if(bwc_compress(field, file)) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + if(retrieve_arg(args, "output")) + { + if(write_file(args, file, "output")) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + } + else + { + if(write_file(args, file, "compress")) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + } + temp = retrieve_arg(args, "verbose"); + if(temp != NULL) + { + /*--------------------------------------------------------*\ + ! Calculate the original field size, compression ratio and ! + ! bits per datapoint and print the miscellaneous compres- ! + ! sion information to the standard output. ! + \*--------------------------------------------------------*/ + if((temp->count == 1) && (temp->num_opt[0] > 1) && (control->CSsgc != 0)) + { + printf("==============================================================\n"); + printf(" \n"\ + " .:-------------: .:-------------: \n"\ + " .+++++++++++++++= :+++++++++++++++- \n"\ + " :+++. -++= -++= \n"\ + " :+++. -++= -++= \n"\ + " -++++++++++++++= -++= -++= \n"\ + " .=++---------=++= -++= -++= \n"\ + " :+++ :++= -++= -++= \n"\ + " .+++=--------=+++---=+++---=+++------------: \n"\ + " -=++++++++++++++++++++++++++++++++++++++++- \n"\ + " \n"); + printf("----------------- Compression Parameters -----------------\n\n"); + if((control->CSsgc &0x200) != 0) + { + printf(" Number of Tiles: %27d\n", control->nTiles); + printf(" - Samples in 1.D: %27ld\n", control->tileSizeX); + printf(" - Samples in 2.D: %27ld\n", control->tileSizeY); + printf(" - Samples in 3.D: %27ld\n", control->tileSizeZ); + printf(" - Timesteps: %27d\n", control->tileSizeTS); + printf(" ..........................................................\n"); + printf("\n"); + } + + if((control->CSsgc &0xE0) != 0) + { + printf(" 1.D | 2.D | 3.D | TS\n"); + if((control->CSsgc &0x20) != 0) + { + printf(" Decomposition Levels: %2d | %2d | %2d | %2d\n", control->decompX + , control->decompY + , control->decompZ + , control->decompTS); + } + if((control->CSsgc &0x40) != 0) + { + printf(" Precincts [log2]: %2d | %2d | %2d | %2d\n", control->precSizeX + , control->precSizeY + , control->precSizeZ + , control->precSizeTS); + + } + if((control->CSsgc &0x80) != 0) + { + printf(" Codeblocks [log2]: %2d | %2d | %2d | %2d\n", control->cbX + , control->cbY + , control->cbZ + , control->cbTS); + } + printf(" ..........................................................\n"); + printf("\n"); + } + + if((control->CSsgc &0x101) != 0) + { + if((control->CSsgc &0x100) != 0) + printf(" Q Number Format: %27d\n", control->Qm); + if((control->CSsgc &0x1) != 0) + printf(" Error Resilience: %27s\n", ((control->error_resilience > 0) ? "True" : "False")); + + printf(" ..........................................................\n"); + printf("\n"); + } + + for(i = 0; i < control->nLayers; ++i) + { + printf(" Quality Layer Nr. %2ld: %23.2f bpd\n", i + 1, control->bitrate[i]/8.0f); + } + + printf("\n"); + printf("---------------- Compression Performance -----------------\n\n"); + } + else + { + printf("==============================================================\n"); + } + + /*--------------------------------------------------------*\ + ! Calculate the original field size, compression ratio and ! + ! bits per datapoint and print the miscellaneous compres- ! + ! sion information to the standard output. ! + \*--------------------------------------------------------*/ + if(file->info.parameter) + { + param = file->info.parameter->root; + + while(param != NULL) + { + size += (param->size * param->precision); + param = param -> next; + } + } + + comp_ratio = (double)size/(file->codestream.data->size); + bpd = (double)(file->codestream.data->size * 64)/size; + + /*--------------------------------------------------------*\ + ! Calculate the original field size, compression ratio and ! + ! bits per datapoint and print the miscellaneous compres- ! + ! sion information to the standard output. ! + \*--------------------------------------------------------*/ + csSize = get_size(file->codestream.data->size); + fdSize = get_size(size); + + /*--------------------------------------------------------*\ + ! Calculate the original field size, compression ratio and ! + ! bits per datapoint and print the miscellaneous compres- ! + ! sion information to the standard output. ! + \*--------------------------------------------------------*/ + printf(" Compression Time: %*.2f s\n", 25, field->meter.time.ttl); + printf(" - Wavelet transformation: %*.2f s\n", 25, field->meter.time.wav); + printf(" - Entropy encoding: %*.2f s\n", 25, field->meter.time.ent); + printf(" - Codestream assembly: %*.2f s\n", 25, field->meter.time.ass); + printf("\n"); + printf(" Compression Ratio: %*.2f\n", 27, comp_ratio); + printf(" - Codestream size: %*s\n", 25, csSize); + printf(" - Field size: %*s\n", 25, fdSize); + printf(" - Average bpd: %*.2f\n", 27, bpd); + printf("==============================================================\n"); + + /*--------------------------------------------------------*\ + ! Calculate the original field size, compression ratio and ! + ! bits per datapoint and print the miscellaneous compres- ! + ! sion information to the standard output. ! + \*--------------------------------------------------------*/ + free(csSize); + free(fdSize); + } + } + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + else if(retrieve_arg(args, "decompress") != NULL) + { + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + if(retrieve_arg(args, "input")) + file = read_file(args, "input"); + else + file = read_file(args, "decompress"); + + if(file == NULL) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + + if(file->codestream.data == NULL) + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: File |\n"\ + "| |\n"\ + "| Input file does not contain a packed code- |\n"\ + "| stream. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + + error_handle = EXIT_FAILURE; + goto OUT; + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + temp = retrieve_arg(args, "layer"); + if((temp != NULL) && (temp->count == 1)) + field = bwc_create_decompression(file, (uint8_t)temp->num_opt[0]); + else + field = bwc_create_decompression(file, 0); + + if(field == NULL) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + temp = retrieve_arg(args, "number_of_threads"); + if((temp != NULL) && (temp->count == 1)) + { + bwc_set_nThreads(field, (uint8_t)temp->num_opt[0]); + } + #endif + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + if(bwc_decompress(field, file)) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + if(retrieve_arg(args, "output")) + { + if(write_file(args, file, "output")) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + } + else + { + if(write_file(args, file, "decompress")) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + } + + /*--------------------------------------------------------*\ + ! If the verbose flag is set by the function caller, print ! + ! the miscellaneous decompression information to the stan- ! + ! dard output. ! + \*--------------------------------------------------------*/ + temp = retrieve_arg(args, "verbose"); + if(temp != NULL) + { + printf("==============================================================\n"); + printf("Decompression Time: %*.2f s\n", 24, field->meter.time.ttl); + printf(" - Wavelet transformation: %*.2f s\n", 24, field->meter.time.wav); + printf(" - Entropy encoding: %*.2f s\n", 24, field->meter.time.ent); + printf("==============================================================\n"); + } + } + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + else if(retrieve_arg(args, "info") != NULL) + { + if(retrieve_arg(args, "input")) + output_info(args, "input"); + else + output_info(args, "info"); + } + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + else if(retrieve_arg(args, "analysis") != NULL) + { + if(output_analysis(args) == EXIT_FAILURE) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + } + /*--------------------------------------------------------*\ + ! ! + \*--------------------------------------------------------*/ + else + { + print_help(); + goto OUT; + } + +OUT: + if(field != NULL) + { + bwc_kill_compression(field); + } + + if(file != NULL) + { + bwc_free_data(file); + } + + if(args != NULL) + { + bwc_kill_arg(args); + } + + fclose(stdin); + fclose(stdout); + fclose(stderr); + + return error_handle; +} \ No newline at end of file diff --git a/src/tools/get_hash.c b/src/tools/get_hash.c new file mode 100755 index 0000000..360023a --- /dev/null +++ b/src/tools/get_hash.c @@ -0,0 +1,154 @@ +/*==================================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| FILE NAME: get_hash.c || +|| || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This is a simple command line tool that converts the command-line arguments to a uniquely identifiable || +|| hash. || +|| || +|| || +|| PUBLIC FUNCTIONS: || +|| ----------------- || +|| - main || +|| || +|| DEVELOPMENT HISTORY: || +|| -------------------- || +|| || +|| Date Author Change Id Release Description Of Change || +|| ---- ------ --------- ------- --------------------- || +|| 02.05.2019 Patrick Vogler B87D120 V 0.1.0 module created || +|| || +|| -------------------------------------------------------------------------------------------------------------------- || +|| || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and || +|| the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions || +|| and the following disclaimer in the documentation and/or other materials provided with the || +|| distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, || +|| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE || +|| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, || +|| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR || +|| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, || +|| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE || +|| USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*==================================================================================================================================*/ + +/************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\************************************************************************************************************/ +#include +#include +#include +#include +#include + + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: int main(int argc, char* argv[]) ! +! -------------- ! +! ! +! DESCRIPTION: ! +! ------------ ! +! ! +! This function uses a variant of the DJB hash function to turn the command-line argument ! +! strings and converts them to a uniquely identifiable hash. The hashes are written to the ! +! command-line in a hexadecimal format. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! argc int - Number of strings pointed to by argv. ! +! ! +! argv char** - Array of arguments. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! int - Return value signaling a normal or abnormal process exit. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description Of Change ! +! ---- ------ --------- ------- --------------------- ! +! 02.05.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +int main(int argc, char* argv[]) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64_t hash; + uint8_t c, i; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char* str; + + /*--------------------------------------------------------*\ + ! Loop through all additional command-line arguments. ! + \*--------------------------------------------------------*/ + for(i = 1, str = argv[1]; i < argc; ++i, str = argv[i]) + { + /*--------------------------------------------------------*\ + ! Initialize the hash with a magic number. ! + \*--------------------------------------------------------*/ + hash = 0x1505; + + /*--------------------------------------------------------*\ + ! Walk through all the characters in the string. ! + \*--------------------------------------------------------*/ + while ((c = *str++)) + { + /*--------------------------------------------------------*\ + ! Convert the current characters to uppercase. ! + \*--------------------------------------------------------*/ + if((c >= 97) && (c <= 122)) + { + c = c - 32; + } + + /*--------------------------------------------------------*\ + ! Multiply the hash with 33 and add the current character ! + ! to the hash. ! + \*--------------------------------------------------------*/ + hash = (hash * 33) ^ c; + } + + /*--------------------------------------------------------*\ + ! Write the hash to the command-line. ! + \*--------------------------------------------------------*/ + printf("%#020lX \n", hash); + } + return 0; +} \ No newline at end of file

}x@WVni-t7ibhf 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