commit bfa813fcb15093aac035e61d2c7063f859629e39 Author: Patrick Vogler Date: Tue Jun 20 13:43:33 2023 +0200 Initial commit 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 0000000..140bbcd Binary files /dev/null and b/docs/img/Logo.png differ 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