From 1ca6d044110ef644e671289120870ba7b95b25b5 Mon Sep 17 00:00:00 2001 From: Patrick Vogler Date: Tue, 20 Jun 2023 13:53:59 +0200 Subject: [PATCH] Initial streaming commit --- CMakeLists.txt | 167 +- Makefile | 4 +- README.md | 2 +- docs/templates/Template.F90 | 158 + docs/templates/Template.c | 183 + docs/templates/Template.py | 121 + docs/templates/Template.txt | 47 + docs/templates/header.h | 299 - docs/templates/source.c | 179 - include/interfaces/fortran/Definition.F90 | 300 + include/interfaces/reader/eas3.h | 480 +- include/interfaces/reader/netCDF.h | 70 + include/library/private/IO.h | 78 + include/library/private/bitstream.h | 310 +- include/library/private/codestream.h | 253 +- include/library/private/constants.h | 418 +- include/library/private/dwt.h | 471 +- include/library/private/field.h | 128 + include/library/private/libbwc.h | 463 +- include/library/private/macros.h | 363 +- include/library/private/mq.h | 259 +- include/library/private/mq_types.h | 329 +- include/library/private/prim_types_double.h | 276 +- include/library/private/prim_types_single.h | 276 +- include/library/private/tagtree.h | 247 +- include/library/private/tier1.h | 295 +- include/library/private/tier2.h | 207 +- include/library/private/types.h | 2791 +++----- include/tools/bwccmdl.h | 432 +- public_header.py | 474 +- src/interfaces/python/bwc.py | 354 +- src/interfaces/reader/eas3.c | 2984 +++++--- src/interfaces/reader/netCDF.c | 1115 +++ src/library/CMakeLists.txt | 166 +- src/library/bitstream.c | 2145 +++--- src/library/codestream.c | 4183 +++++++----- src/library/dwt.c | 4794 +++++++------ src/library/field.c | 3680 ++++++++++ src/library/libbwc.c | 6155 +++++------------ src/library/mq.c | 1132 ++-- src/library/tagtree.c | 1010 +-- src/library/tier1.c | 6726 +++++++++++-------- src/library/tier2.c | 2845 ++++---- src/tools/CMakeLists.txt | 135 +- src/tools/bwccmdl.c | 88 +- src/tools/get_hash.c | 154 - src/tools/test.c | 640 ++ 47 files changed, 25931 insertions(+), 22455 deletions(-) mode change 100755 => 100644 Makefile create mode 100644 docs/templates/Template.F90 create mode 100755 docs/templates/Template.c create mode 100644 docs/templates/Template.py create mode 100644 docs/templates/Template.txt delete mode 100755 docs/templates/header.h delete mode 100755 docs/templates/source.c create mode 100644 include/interfaces/fortran/Definition.F90 mode change 100644 => 100755 include/interfaces/reader/eas3.h create mode 100755 include/interfaces/reader/netCDF.h create mode 100755 include/library/private/IO.h create mode 100644 include/library/private/field.h mode change 100644 => 100755 src/interfaces/reader/eas3.c create mode 100755 src/interfaces/reader/netCDF.c create mode 100644 src/library/field.c delete mode 100755 src/tools/get_hash.c create mode 100644 src/tools/test.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 64b7c50..4e337d6 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,105 +1,96 @@ -#*====================================================================================================================*# -#| |# -#| /$$$$$$$ /$$ /$$ /$$ /$$ |# -#| | $$__ $$|__/ | $$ /$ | $$| $$ |# -#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# -#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# -#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# -#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# -#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# -#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# -#| /$$ \ $$ | $$ |# -#| | $$$$$$/ | $$ |# -#| \______/ |__/ |# -#| 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. |# -#| |# -#*====================================================================================================================*# -#*--------------------------------------------------------*# +#*================================================================================================*# +#| |# +#| /$$$$$$$ /$$ /$$ /$$ /$$ |# +#| | $$__ $$|__/ | $$ /$ | $$| $$ |# +#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# +#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# +#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# +#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# +#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# +#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# +#| /$$ \ $$ | $$ |# +#| | $$$$$$/ | $$ |# +#| \______/ |__/ |# +#| |# +#| DESCRIPTION: |# +#| ------------ |# +#| |# +#| Defines the global cmake script for the Big Whoop compression algorithm. |# +#| |# +#| -------------------------------------------------------------------------------------------- |# +#| 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. |# +#| |# +#*================================================================================================*# +#----------------------------------------------------------# # 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}) +string(REGEX MATCH "V[ \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() +if("${TOOL}" STREQUAL "True" AND NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BWC_SOURCE_DIR}/${CMAKE_INSTALL_BINDIR}) endif() if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${BWC_SOURCE_DIR}/${CMAKE_INSTALL_LIBDIR}) @@ -108,18 +99,18 @@ 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) @@ -127,10 +118,10 @@ 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) @@ -140,22 +131,22 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Release") 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") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-comment -Wextra") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-comment -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 @@ -171,14 +162,14 @@ 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}) +#----------------------------------------------------------# +if("${TOOL}" STREQUAL "True") add_subdirectory(src/tools) endif() \ No newline at end of file diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 index 71dbbb7..b8d4499 --- a/Makefile +++ b/Makefile @@ -148,10 +148,10 @@ tool: # Define targets used to activate file format support. # #*--------------------------------------------------------*# eas3: - $(eval BUILD_EAS3="True") + $(eval BUILD_EAS3="TRUE") netCDF: - $(eval BUILD_NETCDF="True") + $(eval BUILD_NETCDF="TRUE") #*--------------------------------------------------------*# # Define the wrappers for the compile command targets. # diff --git a/README.md b/README.md index 0d717e9..1c46a6b 100644 --- a/README.md +++ b/README.md @@ -40,4 +40,4 @@ make full 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. +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. \ No newline at end of file diff --git a/docs/templates/Template.F90 b/docs/templates/Template.F90 new file mode 100644 index 0000000..5e5098b --- /dev/null +++ b/docs/templates/Template.F90 @@ -0,0 +1,158 @@ +!*================================================================================================*! +!| |! +!| /$$$$$$$ /$$ /$$ /$$ /$$ |! +!| | $$__ $$|__/ | $$ /$ | $$| $$ |! +!| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |! +!| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |! +!| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |! +!| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |! +!| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |! +!| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |! +!| /$$ \ $$ | $$ |! +!| | $$$$$$/ | $$ |! +!| \______/ |__/ |! +!| |! +!| DESCRIPTION: |! +!| ------------ |! +!| |! +!| DESCRIPTION NEEDED. |! +!| | | |! +!| |! +!| -------------------------------------------------------------------------------------------- |! +!| 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. |! +!| |! +!*================================================================================================*! +module MODULE_FILE + !*-----------------------*! + ! DEFINE INT VARIABLES: ! + !*-----------------------*! + !*-----------------------*! + ! DEFINE FLOAT VARIABLES: ! + !*-----------------------*! + !*-----------------------*! + ! DEFINE CHAR VARIABLES: ! + !*-----------------------*! + !*-----------------------*! + ! DEFINE STRUCTS: ! + !*-----------------------*! + !*--------------------------------------------------------*! + ! COMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENT ! + !*--------------------------------------------------------*! + !************************************************************************************************! + !| _ _ _ ____ _ _ _ ___ ____ |! + !| | |\ | | | | | | \ |___ |! + !| | | \| |___ |___ |__| |__/ |___ |! + !| |! + !************************************************************************************************! + !************************************************************************************************! + !| ___ ____ _ _ _ _ ___ _ _ _ ____ ___ _ _ ___ ____ ____ |! + !| |__] |__/ | |\/| | | | | | |___ | \_/ |__] |___ [__ |! + !| | | \ | | | | | | \/ |___ | | | |___ ___] |! + !| |! + !************************************************************************************************! + !************************************************************************************************! + !| _ _ ____ ____ ____ ____ ____ |! + !| |\/| |__| | |__/ | | [__ |! + !| | | | | |___ | \ |__| ___] |! + !| |! + !************************************************************************************************! + !************************************************************************************************! + !| ____ ____ _ _ ____ ___ ____ _ _ ___ ____ |! + !| | | | |\ | [__ | |__| |\ | | [__ |! + !| |___ |__| | \| ___] | | | | \| | ___] |! + !| |! + !************************************************************************************************! + !************************************************************************************************! + !| ____ _ _ ___ ____ ____ _ _ ____ _ _ _ ____ ____ _ ____ ___ _ ____ ____ |! + !| |___ \/ | |___ |__/ |\ | |__| | | | |__| |__/ | |__| |__] | |___ [__ |! + !| |___ _/\_ | |___ | \ | \| | | |___ \/ | | | \ | | | |__] |___ |___ ___] |! + !| |! + !************************************************************************************************! + !************************************************************************************************! + !| ____ _ _ ___ ____ ____ _ _ ____ _ ____ ____ _ _ ____ ___ ____ _ _ ___ ____ |! + !| |___ \/ | |___ |__/ |\ | |__| | | | | |\ | [__ | |__| |\ | | [__ |! + !| |___ _/\_ | |___ | \ | \| | | |___ |___ |__| | \| ___] | | | | \| | ___] |! + !| |! + !************************************************************************************************! + !************************************************************************************************! + !| ____ _ ____ ___ ____ _ ____ ____ _ _ ____ ___ ____ _ _ ___ ____ |! + !| | __ | | | |__] |__| | | | | |\ | [__ | |__| |\ | | [__ |! + !| |__] |___ |__| |__] | | |___ |___ |__| | \| ___] | | | | \| | ___] |! + !| |! + !************************************************************************************************! + !************************************************************************************************! + !| ___ _ _ ___ ____ ____ |! + !| | \_/ |__] |___ [__ |! + !| | | | |___ ___] |! + !| |! + !************************************************************************************************! + !************************************************************************************************! + !| ___ ____ ____ ____ _ _ _ ____ ___ ___ _ _ ___ ____ ____ |! + !| | \ |___ |__/ |__/ | | | |___ | \ | \_/ |__] |___ [__ |! + !| |__/ |___ | \ | \ | \/ |___ |__/ | | | |___ ___] |! + !| |! + !************************************************************************************************! + !------------------------------------------------------------------------------------------------! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + !------------------------------------------------------------------------------------------------! + !============================|=========================|========================================== + !************************************************************************************************! + !| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ |! + !| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ |! + !| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] |! + !| |! + !************************************************************************************************! + !************************************************************************************************! + !| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ |! + !| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ |! + !| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] |! + !| |! + !************************************************************************************************! + !------------------------------------------------------------------------------------------------! + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + ! ARGUMENTS: ! + ! ---------- ! + ! Name Description ! + ! ---- ----------- ! + ! - - ! + ! ! + ! RETURN: ! + ! ------- ! + ! - ! + ! ! + !------------------------------------------------------------------------------------------------! + !===========|==========================|======================|======|=======|==================== + !================================================================================================= +end module MODULE_FILE \ No newline at end of file diff --git a/docs/templates/Template.c b/docs/templates/Template.c new file mode 100755 index 0000000..0f8b07e --- /dev/null +++ b/docs/templates/Template.c @@ -0,0 +1,183 @@ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| DESCRIPTION NEEDED. || +|| | | || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ +/**************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\**************************************************************************************************/ +/**************************************************************************************************\ +|| ____ _ _ ___ ____ ____ _ _ ____ _ _ _ ____ ____ _ ____ ___ _ ____ ____ || +|| |___ \/ | |___ |__/ |\ | |__| | | | |__| |__/ | |__| |__] | |___ [__ || +|| |___ _/\_ | |___ | \ | \| | | |___ \/ | | | \ | | | |__] |___ |___ ___] || +|| || +\**************************************************************************************************/ +/**************************************************************************************************\ +|| ____ _ _ ___ ____ ____ _ _ ____ _ ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || +|| |___ \/ | |___ |__/ |\ | |__| | | | | |\ | [__ | |__| |\ | | [__ || +|| |___ _/\_ | |___ | \ | \| | | |___ |___ |__| | \| ___] | | | | \| | ___] || +|| || +\**************************************************************************************************/ +/**************************************************************************************************\ +|| ____ _ ____ ___ ____ _ ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || +|| | __ | | | |__] |__| | | | | |\ | [__ | |__| |\ | | [__ || +|| |__] |___ |__| |__] | | |___ |___ |__| | \| ___] | | | | \| | ___] || +|| || +\**************************************************************************************************/ +/**************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**************************************************************************************************/ +/**************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**************************************************************************************************/ +/*------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! ! +! DESCRIPTION NEEDED ! +! | | ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! - - ! +! ! +! RETURN: ! +! ------- ! +! - ! +! ! +\*------------------------------------------------------------------------------------------------*/ +/*-----------------------*\ +! DEFINE INT VARIABLES: ! +\*-----------------------*/ +/*-----------------------*\ +! DEFINE FLOAT VARIABLES: ! +\*-----------------------*/ +/*-----------------------*\ +! DEFINE CHAR VARIABLES: ! +\*-----------------------*/ +/*-----------------------*\ +! DEFINE STRUCTS: ! +\*-----------------------*/ +/*--------------------------------------------------------*\ +! COMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENT ! +\*--------------------------------------------------------*/ +#ifndef HEADER_H +#define HEADER_H + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + /************************************************************************************************\ + || ___ ____ _ _ _ _ ___ _ _ _ ____ ___ _ _ ___ ____ ____ || + || |__] |__/ | |\/| | | | | | |___ | \_/ |__] |___ [__ || + || | | \ | | | | | | \/ |___ | | | |___ ___] || + || || + \************************************************************************************************/ + /************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \************************************************************************************************/ + /************************************************************************************************\ + || ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || + || | | | |\ | [__ | |__| |\ | | [__ || + || |___ |__| | \| ___] | | | | \| | ___] || + || || + \************************************************************************************************/ + /************************************************************************************************\ + || ____ _ _ ___ ____ ____ _ _ ____ _ _ _ ____ ____ _ ____ ___ _ ____ ____ || + || |___ \/ | |___ |__/ |\ | |__| | | | |__| |__/ | |__| |__] | |___ [__ || + || |___ _/\_ | |___ | \ | \| | | |___ \/ | | | \ | | | |__] |___ |___ ___] || + || || + \************************************************************************************************/ + /************************************************************************************************\ + || ____ _ _ ___ ____ ____ _ _ ____ _ ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || + || |___ \/ | |___ |__/ |\ | |__| | | | | |\ | [__ | |__| |\ | | [__ || + || |___ _/\_ | |___ | \ | \| | | |___ |___ |__| | \| ___] | | | | \| | ___] || + || || + \************************************************************************************************/ + /************************************************************************************************\ + || ___ _ _ ___ ____ ____ || + || | \_/ |__] |___ [__ || + || | | | |___ ___] || + || || + \************************************************************************************************/ + /************************************************************************************************\ + || ___ ____ ____ ____ _ _ _ ____ ___ ___ _ _ ___ ____ ____ || + || | \ |___ |__/ |__/ | | | |___ | \ | \_/ |__] |___ [__ || + || |__/ |___ | \ | \ | \/ |___ |__/ | | | |___ ___] || + || || + \************************************************************************************************/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + //===========================|=========================|========================================== + /************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************/ + //==========|==========================|======================|======|=======|==================== + //================================================================================================ +#endif \ No newline at end of file diff --git a/docs/templates/Template.py b/docs/templates/Template.py new file mode 100644 index 0000000..ed0f1ee --- /dev/null +++ b/docs/templates/Template.py @@ -0,0 +1,121 @@ +#*================================================================================================*# +#| |# +#| /$$$$$$$ /$$ /$$ /$$ /$$ |# +#| | $$__ $$|__/ | $$ /$ | $$| $$ |# +#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# +#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# +#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# +#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# +#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# +#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# +#| /$$ \ $$ | $$ |# +#| | $$$$$$/ | $$ |# +#| \______/ |__/ |# +#| |# +#| DESCRIPTION: |# +#| ------------ |# +#| |# +#| DESCRIPTION NEEDED. |# +#| | | |# +#| |# +#| -------------------------------------------------------------------------------------------- |# +#| 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. |# +#| |# +#*================================================================================================*# +#**************************************************************************************************# +#| _ _ _ ___ ____ ____ ___ |# +#| | |\/| |__] | | |__/ | |# +#| | | | | |__| | \ | |# +#| |# +#**************************************************************************************************# +#**************************************************************************************************# +#| ____ ____ _ _ ____ ___ ____ _ _ ___ ____ |# +#| | | | |\ | [__ | |__| |\ | | [__ |# +#| |___ |__| | \| ___] | | | | \| | ___] |# +#| |# +#**************************************************************************************************# +#**************************************************************************************************# +#| ____ _ _ ___ ____ ____ _ _ ____ _ _ _ ____ ____ _ ____ ___ _ ____ ____ |# +#| |___ \/ | |___ |__/ |\ | |__| | | | |__| |__/ | |__| |__] | |___ [__ |# +#| |___ _/\_ | |___ | \ | \| | | |___ \/ | | | \ | | | |__] |___ |___ ___] |# +#| |# +#**************************************************************************************************# +#**************************************************************************************************# +#| ____ _ _ ___ ____ ____ _ _ ____ _ ____ ____ _ _ ____ ___ ____ _ _ ___ ____ |# +#| |___ \/ | |___ |__/ |\ | |__| | | | | |\ | [__ | |__| |\ | | [__ |# +#| |___ _/\_ | |___ | \ | \| | | |___ |___ |__| | \| ___] | | | | \| | ___] |# +#| |# +#**************************************************************************************************# +#**************************************************************************************************# +#| ____ _ ____ ___ ____ _ ____ ____ _ _ ____ ___ ____ _ _ ___ ____ |# +#| | __ | | | |__] |__| | | | | |\ | [__ | |__| |\ | | [__ |# +#| |__] |___ |__| |__] | | |___ |___ |__| | \| ___] | | | | \| | ___] |# +#| |# +#**************************************************************************************************# +#**************************************************************************************************# +#| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ |# +#| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ |# +#| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] |# +#| |# +#**************************************************************************************************# +#**************************************************************************************************# +#| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ |# +#| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ |# +#| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] |# +#| |# +#**************************************************************************************************# +#==================================================================================================# +#--------------------------------------------------------------------------------------------------# +# # +# DESCRIPTION: # +# ------------ # +# # +# DESCRIPTION NEEDED # +# | | # +# # +# ARGUMENTS: # +# ---------- # +# Name Description # +# ---- ----------- # +# - - # +# # +# RETURN: # +# ------- # +# - # +# # +#--------------------------------------------------------------------------------------------------# +#-------------------------# +# DEFINE INT VARIABLES: # +#-------------------------# +#-------------------------# +# DEFINE FLOAT VARIABLES: # +#-------------------------# +#-------------------------# +# DEFINE CHAR VARIABLES: # +#-------------------------# +#-------------------------# +# DEFINE STRUCTS: # +#-------------------------# +#----------------------------------------------------------# +# COMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENT # +#----------------------------------------------------------# \ No newline at end of file diff --git a/docs/templates/Template.txt b/docs/templates/Template.txt new file mode 100644 index 0000000..49253d4 --- /dev/null +++ b/docs/templates/Template.txt @@ -0,0 +1,47 @@ +#*================================================================================================*# +#| |# +#| /$$$$$$$ /$$ /$$ /$$ /$$ |# +#| | $$__ $$|__/ | $$ /$ | $$| $$ |# +#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# +#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# +#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# +#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# +#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# +#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# +#| /$$ \ $$ | $$ |# +#| | $$$$$$/ | $$ |# +#| \______/ |__/ |# +#| |# +#| DESCRIPTION: |# +#| ------------ |# +#| |# +#| DESCRIPTION NEEDED. |# +#| | | |# +#| |# +#| -------------------------------------------------------------------------------------------- |# +#| 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. |# +#| |# +#*================================================================================================*# +#----------------------------------------------------------# +# COMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENTCOMMENT # +#----------------------------------------------------------# \ No newline at end of file diff --git a/docs/templates/header.h b/docs/templates/header.h deleted file mode 100755 index 82dc3df..0000000 --- a/docs/templates/header.h +++ /dev/null @@ -1,299 +0,0 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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 deleted file mode 100755 index 626cde2..0000000 --- a/docs/templates/source.c +++ /dev/null @@ -1,179 +0,0 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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/fortran/Definition.F90 b/include/interfaces/fortran/Definition.F90 new file mode 100644 index 0000000..a3aca8f --- /dev/null +++ b/include/interfaces/fortran/Definition.F90 @@ -0,0 +1,300 @@ +!*================================================================================================*! +!| |! +!| /$$$$$$$ /$$ /$$ /$$ /$$ |! +!| | $$__ $$|__/ | $$ /$ | $$| $$ |! +!| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |! +!| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |! +!| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |! +!| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |! +!| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |! +!| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |! +!| /$$ \ $$ | $$ |! +!| | $$$$$$/ | $$ |! +!| \______/ |__/ |! +!| |! +!| DESCRIPTION: |! +!| ------------ |! +!| |! +!| This file defines a FORTRAN api for the Big Whoop compression library. |! +!| |! +!| -------------------------------------------------------------------------------------------- |! +!| 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. |! +!| |! +!*================================================================================================*! +module bwc_module + !************************************************************************************************! + !| _ _ _ ____ _ _ _ ___ ____ |! + !| | |\ | | | | | | \ |___ |! + !| | | \| |___ |___ |__| |__/ |___ |! + !| |! + !************************************************************************************************! + use, intrinsic :: iso_c_binding, only: C_PTR, C_INT64_T, C_INT16_T, C_INT8_T, C_INT, C_DOUBLE + + + IMPLICIT NONE + PRIVATE + !************************************************************************************************! + !| ____ ____ _ _ ____ ___ ____ _ _ ___ ____ |! + !| | | | |\ | [__ | |__| |\ | | [__ |! + !| |___ |__| | \| ___] | | | | \| | ___] |! + !| |! + !************************************************************************************************! + ENUM, BIND(C) + enumerator :: bwc_dwt_9_7 = 0, & ! Cohen Daubechies Feauveau 9/7 Wavelet + bwc_dwt_5_3 = 1, & ! LeGall 5/3 Wavelet + bwc_dwt_haar = 2 ! Haar Wavelet + END ENUM + + ENUM, BIND(C) + enumerator :: bwc_prog_LRCP = 0 ! Layer / Resolution / Parameter / Packet + END ENUM + + ENUM, BIND(C) + enumerator :: bwc_qt_none = 0, & ! No quantization + bwc_qt_derived = 1 ! Derived quantization acc. to JPEG2000 + END ENUM + + ENUM, BIND(C) + enumerator :: bwc_tile_sizeof = 0, & ! Tiling def. through dimension of a tile + bwc_tile_numbof = 1 ! Tiling def. through number of tiles + END ENUM + + !************************************************************************************************! + !| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ |! + !| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ |! + !| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] |! + !| |! + !************************************************************************************************! + interface + subroutine bwc_free_field(field) BIND(C, NAME="bwc_free_field") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + end subroutine bwc_free_field + !=============================================================================================== + subroutine bwc_add_param(field, name, sample, dim, precision) BIND(C, NAME="bwc_add_param") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + TYPE(C_PTR), VALUE :: name + + !*-----------------------*! + ! DEFINE INT VARIABLES: ! + !*-----------------------*! + INTEGER(C_INT16_T) :: sample + + INTEGER(C_INT8_T) :: dimprecision + INTEGER(C_INT8_T) :: precision + end subroutine bwc_add_param + !=============================================================================================== + subroutine bwc_set_tiles(field, tilesX, tilesY, & + tilesZ, tilesTS, instr) BIND(C, NAME="bwc_set_tiles") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + TYPE(C_PTR), VALUE :: instr + + !*-----------------------*! + ! DEFINE INT VARIABLES: ! + !*-----------------------*! + INTEGER(C_INT64_T) :: tilesX, tilesY + INTEGER(C_INT64_T) :: tilesZ, tilesTS + end subroutine bwc_set_tiles + !=============================================================================================== + subroutine bwc_set_kernels(field, KernelX, KernelY, & + KernelZ, KernelTS) BIND(C, NAME="bwc_set_kernels") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + + !*-----------------------*! + ! DEFINE INT VARIABLES: ! + !*-----------------------*! + INTEGER(C_INT) :: KernelX, KernelY + INTEGER(C_INT) :: KernelZ, KernelTS + end subroutine bwc_set_kernels + !=============================================================================================== + subroutine bwc_set_decomp(field, numDecompX, numDecompY, & + numDecompZ, numDecompTS) BIND(C, NAME="bwc_set_decomp") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + + !*-----------------------*! + ! DEFINE INT VARIABLES: ! + !*-----------------------*! + INTEGER(C_INT8_T) :: numDecompX, numDecompY + INTEGER(C_INT8_T) :: numDecompZ, numDecompTS + end subroutine bwc_set_decomp + !=============================================================================================== + subroutine bwc_set_precincts(field, pX, pY, pZ, pTS) BIND(C, NAME="bwc_set_precincts") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + + !*-----------------------*! + ! DEFINE INT VARIABLES: ! + !*-----------------------*! + INTEGER(C_INT8_T) :: pX, pY + INTEGER(C_INT8_T) :: pZ, pTS + end subroutine bwc_set_precincts + !=============================================================================================== + subroutine bwc_set_codeblocks(field, cbX, cbY, cbZ, cbTS) BIND(C, NAME="bwc_set_codeblocks") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + + !*-----------------------*! + ! DEFINE INT VARIABLES: ! + !*-----------------------*! + INTEGER(C_INT8_T) :: cbX, cbY + INTEGER(C_INT8_T) :: cbZ, cbTS + end subroutine bwc_set_codeblocks + !=============================================================================================== + subroutine bwc_set_progression(field, progression) BIND(C, NAME="bwc_set_progression") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + + !*-----------------------*! + ! DEFINE INT VARIABLES: ! + !*-----------------------*! + INTEGER(C_INT) :: progression + end subroutine bwc_set_progression + !=============================================================================================== + subroutine bwc_set_error_resilience(field) BIND(C, NAME="bwc_set_error_resilience") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + end subroutine bwc_set_error_resilience + !=============================================================================================== + subroutine bwc_set_quant_style(field, quantization_style) BIND(C, NAME="bwc_set_quant_style") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + + !*-----------------------*! + ! DEFINE INT VARIABLES: ! + !*-----------------------*! + INTEGER(C_INT) :: quantization_style + end subroutine bwc_set_quant_style + !=============================================================================================== + subroutine bwc_set_qm(field, Qm) BIND(C, NAME="bwc_set_qm") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + + !*-----------------------*! + ! DEFINE INT VARIABLES: ! + !*-----------------------*! + INTEGER(C_INT8_T) :: Qm + end subroutine bwc_set_qm + !=============================================================================================== + subroutine bwc_set_quant_step_size(field, delta) BIND(C, NAME="bwc_set_quant_step_size") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + + !*-----------------------*! + ! DEFINE REAL VARIABLES: ! + !*-----------------------*! + REAL(C_DOUBLE) :: delta + end subroutine bwc_set_quant_step_size + !=============================================================================================== + #ifdef _OPENMP + subroutine bwc_set_nThreads(field, nThreads) BIND(C, NAME="bwc_set_nThreads") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + + !*-----------------------*! + ! DEFINE INT VARIABLES: ! + !*-----------------------*! + INTEGER(C_INT8_T) :: nThreads + end subroutine bwc_set_nThreads + #endif + !=============================================================================================== + subroutine bwc_set_memory_limit(field, limit) BIND(C, NAME="bwc_set_memory_limit") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + TYPE(C_PTR), VALUE :: limit + end subroutine bwc_set_memory_limit + !=============================================================================================== + function bwc_compress(field, rate_control) result(flag) BIND(C, NAME="bwc_compress") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + TYPE(C_PTR), VALUE :: rate_control + + !*-----------------------*! + ! DEFINE INT VARIABLES: ! + !*-----------------------*! + INTEGER(C_INT8_T) :: flag + end function bwc_compress + !=============================================================================================== + function bwc_decompress(field, layer) result(e_flag) BIND(C, NAME="bwc_decompress") + IMPORT + !*-----------------------*! + ! DEFINE POINTERS: ! + !*-----------------------*! + TYPE(C_PTR), VALUE :: field + + !*-----------------------*! + ! DEFINE INT VARIABLES: ! + !*-----------------------*! + INTEGER(C_INT8_T) :: layer + INTEGER(C_INT8_T) :: e_flag + end function bwc_decompress + end interface +end module bwc_module \ No newline at end of file diff --git a/include/interfaces/reader/eas3.h b/include/interfaces/reader/eas3.h old mode 100644 new mode 100755 index 702adde..16a6ffa --- a/include/interfaces/reader/eas3.h +++ b/include/interfaces/reader/eas3.h @@ -1,336 +1,170 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This file defines macros, structs and simple read and write functions used to || +|| access conforming eas3 datasets. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #ifndef EAS3_H #define EAS3_H - /************************************************************************************************************\ - || _ _ _ ____ _ _ _ ___ ____ || - || | |\ | | | | | | \ |___ || - || | | \| |___ |___ |__| |__/ |___ || - || || - \************************************************************************************************************/ - #include - #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 + #include "types.h" + /************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \************************************************************************************************/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros define EAS3 header markers. For more information see: ! + ! https://wiki.iag.uni-stuttgart.de/eas3wiki/index.php/Main_Page/de ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define EAS3_NO_ATTR 0x100000000000000 // No attributes present in the bitstream + #define EAS3_ALL_ATTR 0x200000000000000 // All attributes present in the bitstream - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 // EAS2 Datatype + #define EAS3_TYPE 0x200000000000000 // EAS3 Datatype - #define EAS2_TYPE 0x100000000000000 - #define EAS3_TYPE 0x200000000000000 + #define ATTRLEN 10 // Number of bytes defining an attribute + #define UDEFLEN 20 // Number of bytes defining data - #define ATTRLEN 10 - #define UDEFLEN 20 + #define EAS3_NO_G 0x100000000000000 // No geometry data present in bitstream + #define EAS3_X0DX_G 0x200000000000000 // Start value & step size present + #define EAS3_UDEF_G 0x300000000000000 // Number of grid points present + #define EAS3_ALL_G 0x400000000000000 // Element for every appr. dim. present + #define EAS3_FULL_G 0x500000000000000 // Element for every dimension present - #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 // No user defined data present in bitstr + #define EAS3_ALL_UDEF 0x200000000000000 // All user defined fields present + #define EAS3_INT_UDEF 0x300000000000000 // User defined integer field present - #define EAS3_NO_UDEF 0x100000000000000 - #define EAS3_ALL_UDEF 0x200000000000000 - #define EAS3_INT_UDEF 0x300000000000000 + #define AUX_SIZE 0x8000 // Size of auxiliary information stream - #define AUX_SIZE 0x8000 + /************************************************************************************************\ + || ___ _ _ ___ ____ ____ || + || | \_/ |__] |___ [__ || + || | | | |___ ___] || + || || + \************************************************************************************************/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This structure is used to store the standard eas3 header parameters. For a more ! + ! thorough discussion of the eas3 datatype see: ! + ! ! + ! https://wiki.iag.uni-stuttgart.de/eas3wiki/index.php/EAS3_File_Format/de ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 file_type; // Identifier for EAS Type (EAS2/3) + uint64 accuracy; // Accuracy of the eas3 file - /************************************************************************************************************\ - || ___ _ _ ___ ____ ____ || - || | \_/ |__] |___ [__ || - || | | | |___ ___] || - || || - \************************************************************************************************************/ - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + uint64 nzs; // Temporal dimension size + uint64 npar; // No. parameters present in data-set + uint64 ndim1; // 1st spatial dimension size + uint64 ndim2; // 2nd spatial dimension size + uint64 ndim3; // 3rd spatial dimension size + + uint64 attribute_mode; // Attribute of the eas3 file + + uint64 gmode_time; // Geometry mode for the temp. dimension + uint64 gmode_param; // Geometry mode for the parameters + uint64 gmode_dim1; // 1st spatial dimension geometry mode + uint64 gmode_dim2; // 2nd spatial dimension geometry mode + uint64 gmode_dim3; // 3rd spatial dimension geometry mode + + uint64 size_time; // Temporal dimension geometry array size + uint64 size_parameter; // Geometry array size of parameters + uint64 size_dim1; // 1st sptl. dimension geometry array size + uint64 size_dim2; // 2nd sptl. dimension geometry array size + uint64 size_dim3; // 3rd sptl. dimension geometry array size + + uint64 udef_param; // Signals user def. parameters present + uint64 udef_char_size; // Size of user defined char. array + uint64 udef_int_size; // Size of user defined int. array + uint64 udef_real_size; // Size of user defined real array + } eas3_std_params; + + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This structure is used to store all the necessary parameters required to access ! + ! parameters stored in an eas3 file. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 *offset; // Offset of a parameter in a eas3 file + } eas3_file_util; - /************************************************************************************************************\ - || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || - || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || - || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || - || || - \************************************************************************************************************/ - /*----------------------------------------------------------------------------------------------------------*\ - ! 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); + /************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************/ + uchar open_eas3 (bwc_field *const field, + char const *const filename, + char const *mode); + //==========|==========================|======================|======|=======|==================== + uchar load_eas3 (bwc_field *const field, + char const *const filename); + //==========|==========================|======================|======|=======|==================== + uchar unload_eas3 (bwc_field *const field, + char const *const filename); #endif \ No newline at end of file diff --git a/include/interfaces/reader/netCDF.h b/include/interfaces/reader/netCDF.h new file mode 100755 index 0000000..10e5edb --- /dev/null +++ b/include/interfaces/reader/netCDF.h @@ -0,0 +1,70 @@ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This file defines simple read and write functions used to access conforming || +|| netCDF datasets. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ +#ifndef NETCDF_H +#define NETCDF_H + + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + #include + #include + + #include "utilities.h" + + + /************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************/ + bwc_data* read_netCDF (char *const filename); + //==========|==========================|======================|======|=======|==================== + uchar write_netCDF (bwc_data *const file, + char *const filename); +#endif \ No newline at end of file diff --git a/include/library/private/IO.h b/include/library/private/IO.h new file mode 100755 index 0000000..4212e10 --- /dev/null +++ b/include/library/private/IO.h @@ -0,0 +1,78 @@ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This file defines simple read and write functions used to access conforming bwc || +|| datasets. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ +#ifndef IO_H +#define IO_H + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + #include "types.h" + + #ifdef BWC_EAS3 + #include "eas3.h" + #endif + + #ifdef BWC_NETCDF + #include "netcdf.h" + #endif + + /************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************/ + uchar open_bwc (bwc_field *const field, + char const *const filename, + char const *mode); + //==========|==========================|======================|======|=======|==================== + uchar load_bwc (bwc_field *const field, + char const *const filename); + //==========|==========================|======================|======|=======|==================== + uchar unload_bwc (bwc_field *const field, + char const *const filename); +#endif \ No newline at end of file diff --git a/include/library/private/bitstream.h b/include/library/private/bitstream.h index 001bca4..39d5678 100755 --- a/include/library/private/bitstream.h +++ b/include/library/private/bitstream.h @@ -1,224 +1,94 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| 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 codestream and can emit/extract information on a per bit, || +|| symbol (64-bit) or string basis. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #ifndef BITSTREAM_H #define BITSTREAM_H + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + #include "types.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); + /************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************/ + uint64 bytes_used (bwc_stream const *const stream); + //==========|==========================|======================|======|======|===================== + bwc_stream* init_stream (uchar *const memory, + uint32 const size, + char const instr); + //==========|==========================|======================|======|======|===================== + void emit_chunck (bwc_stream *const stream, + uchar const *const chunck, + uint64 const size); + //==========|==========================|======================|======|======|===================== + void emit_symbol (bwc_stream *const stream, + uint64 const symbol, + uint8 const size); + //==========|==========================|======================|======|======|===================== + void emit_bit (bwc_stream *const stream, + uint64 const bit); + //==========|==========================|======================|======|======|===================== + void flush_stream (bwc_stream *const stream); + //==========|==========================|======================|======|======|===================== + uchar* get_chunck (bwc_stream *const stream, + uint64 const length); + //==========|==========================|======================|======|======|===================== + uint64 get_symbol (bwc_stream *const stream, + uint8 const length); + //==========|==========================|======================|======|======|===================== + uchar get_bit (bwc_stream *const stream); + //==========|==========================|======================|======|======|===================== + uchar terminate_stream (bwc_stream *stream, + bwc_packed_stream *const packed_stream); + //==========|==========================|======================|======|======|===================== + void release_packed_stream (bwc_packed_stream *const stream); #endif \ No newline at end of file diff --git a/include/library/private/codestream.h b/include/library/private/codestream.h index 0458d2c..602ad14 100755 --- a/include/library/private/codestream.h +++ b/include/library/private/codestream.h @@ -1,191 +1,70 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This file describes a set of function that can be used to create and manipulate || +|| a BigWhoop Codestream. They facilitate the assembly and parsing of the main || +|| header and tile bitsreams as well as read and write functions used to access || +|| conforming bwc datasets. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #ifndef CODESTREAM_H #define CODESTREAM_H + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + #include "types.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); + /************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************/ + void free_bwc (bwc_field *const field); + //==========|==========================|======================|======|======|===================== + uchar assemble_tile (bwc_field *const field); + //==========|==========================|======================|======|======|===================== + uchar initialize_main_header (bwc_field *const field); + //==========|==========================|======================|======|======|===================== + uchar finalize_main_header (bwc_field *const field); #endif \ No newline at end of file diff --git a/include/library/private/constants.h b/include/library/private/constants.h index c33f78f..7832f62 100755 --- a/include/library/private/constants.h +++ b/include/library/private/constants.h @@ -1,328 +1,102 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This file defines simple constants that are used to make the code more readable. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #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 are used to signal spatial or temporal the wavelet filter. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef enum + { + bwc_dwt_9_7, // Cohen Daubechies Feauveau 9/7 Wavelet + bwc_dwt_5_3, // LeGall 5/3 Wavelet + bwc_dwt_haar // Haar Wavelet + } bwc_dwt_filter; - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 are used to signal the packing order of the codestream. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef enum + { + bwc_prog_LRCP // Layer / Resolution / Parameter / Packet + } bwc_prog_ord; - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 to signal the quantisation style during ! + ! (de)coompression. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef enum + { + bwc_qt_none, // No quantization + bwc_qt_derived, // Derrived according to Taubman/Marcellin + } bwc_quant_st; - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These constants are used to signal dataset tiling by the function caller. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef enum + { + bwc_tile_sizeof, // Tiling defined by size of one tile + bwc_tile_numbof, // Tiling defined by the number of tiles + } bwc_tile_instr; #endif \ No newline at end of file diff --git a/include/library/private/dwt.h b/include/library/private/dwt.h index 8265a03..24d1df2 100755 --- a/include/library/private/dwt.h +++ b/include/library/private/dwt.h @@ -1,328 +1,167 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This file describes a set of functions that can be used to performe the forward/ || +|| inverse discrete wavelet transform on 1- to 4-dimensional IEEE 754 data-sets. || +|| For more information please refere to JPEG2000 by D. S. Taubman and M. W. || +|| Marcellin. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #ifndef DWT_H #define DWT_H - /************************************************************************************************************\ - || _ _ _ ____ _ _ _ ___ ____ || - || | |\ | | | | | | \ |___ || - || | | \| |___ |___ |__| |__/ |___ || - || || - \************************************************************************************************************/ - #include "types.h" + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + #include "types.h" + /************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \************************************************************************************************/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! Maximum number of wavelet layers for which the energy gain is calculated. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define MAX_DECOMP_LEVELS 4 - /************************************************************************************************************\ - || _ _ ____ ____ ____ ____ ____ || - || |\/| |__| | |__/ | | [__ || - || | | | | |___ | \ |__| ___] || - || || - \************************************************************************************************************/ - /*----------------------------------------------------------------------------------------------------------*\ - ! 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. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define DWT_9X7_H0 1.115087052457000f // Low pass synthesis filter ... + #define DWT_9X7_H1 0.591271763114250f // ... coefficients + #define DWT_9X7_H2 -0.057543526228500f + #define DWT_9X7_H3 -0.091271763114250f - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 // High pass synthesis filter ... + #define DWT_9X7_G1 -0.533728236885750f // ... coefficients + #define DWT_9X7_G2 -0.156446533057980f + #define DWT_9X7_G3 0.033728236885750f + #define DWT_9X7_G4 0.053497514821620f - #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 // Lifting coefficients. + #define BETA -0.052980118572961f + #define GAMMA 0.882911075530934f + #define DELTA 0.360523644801462f + #define KAPPA_H 1.230174104914001f + #define KAPPA_L 0.812893066115961f - #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. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define DWT_5X3_H0 1.0f // Low pass synthesis filter ... + #define DWT_5X3_H1 0.5f // ... coefficients - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 // High pass synthesis filter + #define DWT_5X3_G1 -0.25f // ... coefficients + #define DWT_5X3_G2 -0.125f - #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. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define DWT_HAAR_H0 1 // Low pass synthesis filter ... + #define DWT_HAAR_H1 1 // ... coefficients - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 // High pass synthesis filter ... + #define DWT_HAAR_G1 -0.5 // ... coefficients - #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 dimensional 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. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + extern double DWT_ENERGY_GAIN_LUT[3][2 * MAX_DECOMP_LEVELS + 2]; - /************************************************************************************************************\ - || ____ _ _ ___ ____ ____ _ _ ____ _ _ _ ____ ____ _ ____ ___ _ ____ ____ || - || |___ \/ | |___ |__/ |\ | |__| | | | |__| |__/ | |__| |__] | |___ [__ || - || |___ _/\_ | |___ | \ | \| | | |___ \/ | | | \ | | | |__] |___ |___ ___] || - || || - \************************************************************************************************************/ - /*----------------------------------------------------------------------------------------------------------*\ - ! 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); + /************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************/ + uchar initialize_gain_lut (); + //==========|==========================|======================|======|=======|==================== + bwc_float get_dwt_energy_gain (bwc_field *const field, + uchar const highband_flag, + uint16 const level); + //==========|==========================|======================|======|=======|==================== + uchar forward_wavelet_transform (bwc_field *const field, + uint16 const parID); + //==========|==========================|======================|======|=======|==================== + uchar inverse_wavelet_transform (bwc_field *const field, + uint16 const parID); #endif \ No newline at end of file diff --git a/include/library/private/field.h b/include/library/private/field.h new file mode 100644 index 0000000..daade22 --- /dev/null +++ b/include/library/private/field.h @@ -0,0 +1,128 @@ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| Big Whoop is a compression codec for the lossy compression of IEEE 754 floating || +|| point arrays defined on curvelinear compute grids. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ +#ifndef BWC_H +#define BWC_H + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + #include "types.h" + + /************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************/ + uchar create_field (bwc_field *const field); + //==========|==========================|======================|======|=======|==================== + uchar adapt_tile (bwc_field *const field, + uint64 const index); + //==========|==========================|======================|======|=======|==================== + bwc_field* bwc_create_field (); + //==========|==========================|======================|======|=======|==================== + void bwc_free_field (bwc_field *const field); + //==========|==========================|======================|======|=======|==================== + void bwc_add_param (bwc_field *const field, + char const *const name, + uint16 const sample, + uchar const dim, + uint8 const precision); + //==========|==========================|======================|======|=======|==================== + void bwc_set_tiles (bwc_field *const field, + uint64 const tilesX, + uint64 const tilesY, + uint64 const tilesZ, + uint64 const tilesTS, + bwc_tile_instr const instr); + //==========|==========================|======================|======|=======|==================== + void bwc_set_kernels (bwc_field *const field, + bwc_dwt_filter const KernelX, + bwc_dwt_filter const KernelY, + bwc_dwt_filter const KernelZ, + bwc_dwt_filter const KernelTS); + //==========|==========================|======================|======|=======|==================== + void bwc_set_decomp (bwc_field *const field, + uint8 const numDecompX, + uint8 const numDecompY, + uint8 const numDecompZ, + uint8 const numDecompTS); + //==========|==========================|======================|======|=======|==================== + void bwc_set_precincts (bwc_field *const field, + uint8 const pX, + uint8 const pY, + uint8 const pZ, + uint8 const pTS); + //==========|==========================|======================|======|=======|==================== + void bwc_set_codeblocks (bwc_field *const field, + uint8 const cbX, + uint8 const cbY, + uint8 const cbZ, + uint8 const cbTS); + //==========|==========================|======================|======|=======|==================== + void bwc_set_progression (bwc_field *const field, + bwc_prog_ord const progression); + //==========|==========================|======================|======|=======|==================== + void bwc_set_error_resilience (bwc_field *const field); + //==========|==========================|======================|======|=======|==================== + void bwc_set_quant_style (bwc_field *const field, + bwc_quant_st const quantization_style); + //==========|==========================|======================|======|=======|==================== + void bwc_set_qm (bwc_field *const field, + uint8 const Qm); + //==========|==========================|======================|======|=======|==================== + void bwc_set_quant_step_size (bwc_field *const field, + double delta); + //==========|==========================|======================|======|=======|==================== + #if defined(_OPENMP) + void bwc_set_nThreads (bwc_field *const field, + uint8 const nThreads); + #endif + //==========|==========================|======================|======|=======|==================== + void bwc_set_memory_limit (bwc_field *const field, + char *const limit); +#endif \ No newline at end of file diff --git a/include/library/private/libbwc.h b/include/library/private/libbwc.h index fcf36a1..bbc27d2 100755 --- a/include/library/private/libbwc.h +++ b/include/library/private/libbwc.h @@ -1,394 +1,73 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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" +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| Big Whoop is a compression codec for the lossy compression of IEEE 754 floating || +|| point arrays defined on curvelinear compute grids. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ +#ifndef LIBBWC_H +#define LIBBWC_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); + /************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************/ + uchar bwc_open_file (bwc_field *const field, + char const *const filename, + char const *const mode); + //==========|==========================|======================|======|=======|==================== + uchar bwc_load_file (bwc_field *const field, + char const *const filename); + //==========|==========================|======================|======|=======|==================== + uchar bwc_compress (bwc_field *const field, + char *const rate_control); + //==========|==========================|======================|======|=======|==================== + uchar bwc_decompress (bwc_field *const field, + uint8 const layer); #endif \ No newline at end of file diff --git a/include/library/private/macros.h b/include/library/private/macros.h index 749d79e..7b0dd89 100755 --- a/include/library/private/macros.h +++ b/include/library/private/macros.h @@ -1,140 +1,235 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This file defines simple macros that are used to make the code more readable. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #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: ! + ! ------------ ! + ! ! + ! These macros define flags used to indicate if a dataset is to be red from/ ! + ! written to a file or cleared in the bwc_file structure. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define DATA_CLR 0x00 // Data cleared + #define DATA_INI 0x01 // Data file has been initialized + #define DATA_IN 0x10 // Data set as input + #define DATA_OUT 0x20 // Data set as output + #define DATA_STR 0x40 // Data set to be streamed to/from file - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 macros define flags used to indicate if a codestream is to be red from/ ! + ! written to a file or cleared in the bwc_file structure. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define CS_CLR 0x00 // Codestream cleared + #define CS_AUX 0x01 // Codestream contains aux. information + #define CS_COM 0x02 // Codestream contains com. information + #define CS_IN 0x10 // Codestream set as input + #define CS_OUT 0x20 // Codestream set as output + #define CS_STR 0x40 // Codestream to be streamed to/from file - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 macros define flags used to indicate the state of the setup structure in ! + ! the bwc_field structure. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define SETUP_CLR 0x00 // Setup cleared + #define SETUP_CMP 0x01 // Setup defined for compression + #define SETUP_DCP 0x02 // Setup defined for decompression - /*----------------------------------------------------------------------------------------------------------*\ - ! 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" + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros define flags used to indicate the state of the bwc_field structure. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define FIELD_CLR 0x00 // Field cleared and ready to be used + #define FIELD_USD 0x01 // Field setup up for (de)compression + #define FIELD_ERR 0x02 // Field encountered an error + #define FIELD_VRB 0x10 // Store miscallaneous information + + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros are used to identify the spatial and temporal dimensions. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define DIM_X 1 // 1st. spacial direction + #define DIM_Y 2 // 2nd. spacial direction + #define DIM_Z 4 // 3rd. spacial direction + #define DIM_TS 8 // temporal direction + #define DIM_ALL 15 // all dimensions + + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These Constants define codestream markers used to create the embedded codestream. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define SOC 0xFF50 // Start of codestream + #define SGI 0xFF51 // Global data-set information + #define SGC 0xFF52 // Global control parameters + #define SGR 0xFF53 // Global tile bitstream size information + #define SAX 0xFF54 // Auxiliary data-set information + #define TLM 0xFF55 // Packet lengths: main header + #define PLM 0xFF56 // Packet lengths: tile-part + #define PPM 0xFF57 // Quantization default + #define COM 0xFF58 // Comment + #define EOH 0xFF59 // End of header + #define PLT 0xFF60 // Packed packet headers: main header + #define PPT 0xFF61 // Packed packet headers: tile-part + #define SOT 0xFF90 // Start of tile + #define SOP 0xFF91 // Start of packet + #define EPH 0xFF92 // End of packet header + #define SOD 0xFF93 // Start of data + #define EOC 0xFFFF // End of code-stream + + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros define flags used for codestream parsing. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define CODESTREAM_OK 0x00 // No errors detected in Codestream + #define CODESTREAM_ERROR 0x80 // Error detexted in Codestream + #define CODESTREAM_SGI_READ 0x01 // Global data-set information read + #define CODESTREAM_SGC_READ 0x02 // Global control parameters read + #define CODESTREAM_SGR_READ 0x04 // Global register read + #define CODESTREAM_SAX_READ 0x08 // Auxiliary information block read + #define CODESTREAM_COM_READ 0x10 // Comment block read + + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros define simple mathematicall oprators. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define MAX(x, y) (((x) < (y))?(y):(x)) // Returns maximum between two values + #define MIN(x, y) (((x) > (y))?(y):(x)) // Returns minimum between two values + + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros define stream manipulation operations to rewind, forward, inquire ! + ! the availability and get access to the current memory position of a bwc_stream. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define REWIND(stream, delta) \ + { \ + stream->L -= delta; \ + } + + #define FORWARD(stream, delta) \ + { \ + stream->L += delta; \ + } + + #define CAN_READ(stream, length) \ + { \ + ((stream->L + length > stream->Lmax) ? FAILURE : SUCCESS) \ + } + + #define GET_ACCESS(stream) (uchar*)stream->memory + stream->L + + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These Constants define common error messages used throughout the bwc library. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define CSTERROR "o##########################################################o\n"\ + "| ERROR: Invalid Codestream |\n"\ + "o##########################################################o\n" + + #define FRMERROR "o##########################################################o\n"\ + "| ERROR: Invalid file format. |\n"\ + "o##########################################################o\n" + + #define INPERROR "o##########################################################o\n"\ + "| ERROR: No Input Specified. |\n"\ + "o##########################################################o\n" + + #define MEMERROR "o##########################################################o\n"\ + "| ERROR: Out of Memory |\n"\ + "o##########################################################o\n" + + #define PARERROR "o##########################################################o\n"\ + "| ERROR: Invalid Parameter |\n"\ + "o##########################################################o\n" + + #define PRCERROR "o##########################################################o\n"\ + "| ERROR: Invalid Parameter Precision |\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" #endif \ No newline at end of file diff --git a/include/library/private/mq.h b/include/library/private/mq.h index 8a39519..bd17dff 100755 --- a/include/library/private/mq.h +++ b/include/library/private/mq.h @@ -1,155 +1,114 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| DESCRIPTION NEEDED. || +|| | | || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #ifndef MQ_H #define MQ_H + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + #include "tier1.h" + #include "types.h" - /************************************************************************************************************\ - || _ _ _ ____ _ _ _ ___ ____ || - || | |\ | | | | | | \ |___ || - || | | \| |___ |___ |__| |__/ |___ || - || || - \************************************************************************************************************/ - #include "types.h" + /************************************************************************************************\ + || ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || + || | | | |\ | [__ | |__| |\ | | [__ || + || |___ |__| | \| ___] | | | | \| | ___] || + || || + \************************************************************************************************/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros define the context state indices used by the mq coder for ! + ! probability estimation. For a more thorough treatment of the context assignments ! + ! see page 487 JPEG2000 by David S. Taubman and Michael W. Marcellin. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define CONTEXT_SIG 0 // Sig. context labels starting indices + #define CONTEXT_RUN 9 // Indices for the run context label + #define CONTEXT_SIGN 10 // Sign context labels starting indices + #define CONTEXT_MAG 15 // Mag. context labels starting indices + #define CONTEXT_UNI 18 // Indices for the uni context label + #define CONTEXT_TOTAL 19 // Total number of context labels - /************************************************************************************************************\ - || ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || - || | | | |\ | [__ | |__| |\ | | [__ || - || |___ |__| | \| ___] | | | | \| | ___] || - || || - \************************************************************************************************************/ - /*----------------------------------------------------------------------------------------------------------*\ - ! 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); + /************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************/ + uchar initialize_mq_encoder (bwc_coder *const coder, + uint8 const numContexts); + //==========|==========================|======================|======|=======|==================== + uchar mq_next_run (bwc_bit_coder *const bitcoder); + //==========|==========================|======================|======|=======|==================== + void mq_bit_encode (bwc_bit_coder *const bitcoder, + uint8 const s, + uint8 const k); + //==========|==========================|======================|======|=======|==================== + void mq_truncation_length_min (bwc_coder_state *const state); + //==========|==========================|======================|======|=======|==================== + void mq_termination (bwc_bit_coder *const bitcoder); + //==========|==========================|======================|======|=======|==================== + void free_mq_encoder (bwc_coder *const coder); + //==========|==========================|======================|======|=======|==================== + uchar initialize_mq_decoder (bwc_coder *const coder, + uint8 const numContexts, + int64 const Lmax); + //==========|==========================|======================|======|=======|==================== + uint8 mq_bit_decode (bwc_bit_coder *const bitcoder, + uint8 const k); + //==========|==========================|======================|======|=======|==================== + uint64 mq_get_no_bytes (bwc_bit_coder *const bitcoder); + //==========|==========================|======================|======|=======|==================== + void mq_get_pass_lengths (bwc_bit_coder *const bitcoder, + bwc_encoded_blk *const encoded_cblk); + //==========|==========================|======================|======|=======|==================== + void mq_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 index 6f6a93f..84c5c7b 100755 --- a/include/library/private/mq_types.h +++ b/include/library/private/mq_types.h @@ -1,222 +1,121 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This header defines a the bit coder and its context states used during the || +|| entropy encoding stage of the BigWhoop compression library. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #ifndef MQ_TYPES_H #define MQ_TYPES_H + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + #include - /************************************************************************************************************\ - || _ _ _ ____ _ _ _ ___ ____ || - || | |\ | | | | | | \ |___ || - || | | \| |___ |___ |__| |__/ |___ || - || || - \************************************************************************************************************/ - #include + /************************************************************************************************\ + || ___ ____ ____ ____ _ _ _ ____ ___ ___ _ _ ___ ____ ____ || + || | \ |___ |__/ |__/ | | | |___ | \ | \_/ |__] |___ [__ || + || |__/ |___ | \ | \ | \/ |___ |__/ | | | |___ ___] || + || || + \************************************************************************************************/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This structure is used to directly access the parameter codeblocks during ! + ! entropy (de-)encoding to facilitate shared memory parallelization. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct context + { + uint16_t p; // LPS probability estimate + uint8_t sk; // Most probable symbol - /************************************************************************************************************\ - || ___ ____ ____ ____ _ _ _ ____ ___ ___ _ _ ___ ____ ____ || - || | \ |___ |__/ |__/ | | | |___ | \ | \_/ |__] |___ [__ || - || |__/ |___ | \ | \ | \/ |___ |__/ | | | |___ ___] || - || || - \************************************************************************************************************/ - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + const struct context *const MPS; // New context for Most Probable Symbol + const struct context *const LPS; // New context for Least Probable Symbol + } 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; + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct state + { + int64_t L; // Number of bytes generated so far + uint32_t C; // Register def. lower bound of coding int + uint16_t A; // Register def. upper bound of coding int + int8_t t; // Counter evaluating when moving C into b - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + unsigned char *b; // Byte buffer + unsigned char T; // Temporary byte buffer + + struct state *next; // State of the next coding phase + struct state *prev; // State of the previous coding phase + } bwc_coder_state; + + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + int64_t Lmax; // Number of code bytes (used by decoder) + uint8_t nContext; // No. tracked context states + + unsigned char *b; // Temporary byte buffer + + bwc_coder_state *state; // State for the current coding pass + bwc_context_state const **context; // States for the current coding pass + } 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 index 948a83b..4c8fc4b 100755 --- a/include/library/private/prim_types_double.h +++ b/include/library/private/prim_types_double.h @@ -1,163 +1,133 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This header defines a set of basic arithmetic types with specified widths to be || +|| used in the big whoop compression algorithm. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #ifndef BWC_PRIM_TYPES_DOUBLE_H #define BWC_PRIM_TYPES_DOUBLE_H + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + #include - /************************************************************************************************************\ - || _ _ _ ____ _ _ _ ___ ____ || - || | |\ | | | | | | \ |___ || - || | | \| |___ |___ |__| |__/ |___ || - || || - \************************************************************************************************************/ - #include + /************************************************************************************************\ + || ___ ____ _ _ _ _ ___ _ _ _ ____ ___ _ _ ___ ____ ____ || + || |__] |__/ | |\/| | | | | | |___ | \_/ |__] |___ [__ || + || | | \ | | | | | | \/ |___ | | | |___ ___] || + || || + \************************************************************************************************/ + typedef unsigned char uchar; + typedef unsigned short ushort; + typedef unsigned int uint; - /************************************************************************************************************\ - || ___ ____ _ _ _ _ ___ _ _ _ ____ ___ _ _ ___ ____ ____ || - || |__] |__/ | |\/| | | | | | |___ | \_/ |__] |___ [__ || - || | | \ | | | | | | \/ |___ | | | |___ ___] || - || || - \************************************************************************************************************/ - 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 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; - typedef double bwc_float; - typedef uint64 bwc_raw; + /************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \************************************************************************************************/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros describe the minimum and maximum values for a double precision IEEE ! + ! 754 floating point variable. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define FLT_MAX 1.7976931348623157e+308 // Maximum finite value of a double + #define FLT_MIN 2.2250738585072014e-308 // Minimum finite value of a double - /************************************************************************************************************\ - || _ _ ____ ____ ____ ____ ____ || - || |\/| |__| | |__/ | | [__ || - || | | | | |___ | \ |__| ___] || - || || - \************************************************************************************************************/ - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 macros describe the precision (in bits and bytes) of the derrived floating ! + ! point type as well as the number of bits used to represent its mantissa and ! + ! exponent fields. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define PREC_BIT 63 // Double type precision in bits + #define PREC_MANTISSA 52 // Mantissa field precision in bits + #define PREC_EXPONENT 11 // Exponent field precision in bits + #define PREC_BYTE 8 // Double type precision in bytes - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 macros describe the bit masks used to access the sign, mantissa and ! + ! exponent of the derrived floating point type. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define SIGN 0x8000000000000000 // Sign bit mask + #define MANTISSA 0x000FFFFFFFFFFFFF // Mantissa bit mask + #define EXPONENT 0x7FF0000000000000 // Exponent bit mask - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This macro describe the maximum number of possible encoding passes during the ! + ! entropy encoding stage. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #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 index 2c3872e..e2e8365 100755 --- a/include/library/private/prim_types_single.h +++ b/include/library/private/prim_types_single.h @@ -1,163 +1,133 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This header defines a set of basic arithmetic types with specified widths to be || +|| used in the big whoop compression algorithm. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #ifndef BWC_PRIM_TYPES_SINGLE_H #define BWC_PRIM_TYPES_SINGLE_H + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + #include - /************************************************************************************************************\ - || _ _ _ ____ _ _ _ ___ ____ || - || | |\ | | | | | | \ |___ || - || | | \| |___ |___ |__| |__/ |___ || - || || - \************************************************************************************************************/ - #include + /************************************************************************************************\ + || ___ ____ _ _ _ _ ___ _ _ _ ____ ___ _ _ ___ ____ ____ || + || |__] |__/ | |\/| | | | | | |___ | \_/ |__] |___ [__ || + || | | \ | | | | | | \/ |___ | | | |___ ___] || + || || + \************************************************************************************************/ + typedef unsigned char uchar; + typedef unsigned short ushort; + typedef unsigned int uint; - /************************************************************************************************************\ - || ___ ____ _ _ _ _ ___ _ _ _ ____ ___ _ _ ___ ____ ____ || - || |__] |__/ | |\/| | | | | | |___ | \_/ |__] |___ [__ || - || | | \ | | | | | | \/ |___ | | | |___ ___] || - || || - \************************************************************************************************************/ - 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 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; - typedef float bwc_float; - typedef uint32 bwc_raw; + /************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \************************************************************************************************/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros describe the minimum and maximum values for a single precision IEEE ! + ! 754 floating point variable. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define FLT_MAX 1.70141183e+38 // Maximum finite value of a float + #define FLT_MIN 1.17549435e-38 // Minimum finite value of a float - /************************************************************************************************************\ - || _ _ ____ ____ ____ ____ ____ || - || |\/| |__| | |__/ | | [__ || - || | | | | |___ | \ |__| ___] || - || || - \************************************************************************************************************/ - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 macros describe the precision (in bits and bytes) of the derrived floating ! + ! point type as well as the number of bits used to represent its mantissa and ! + ! exponent fields. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define PREC_BIT 31 // Float type precision in bits + #define PREC_MANTISSA 23 // Mantissa field precision in bits + #define PREC_EXPONENT 8 // Exponent field precision in bits + #define PREC_BYTE 4 // Float type precision in bytes - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 macros describe the bit masks used to access the sign, mantissa and ! + ! exponent of the derrived floating point type. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define SIGN 0x80000000 // Sign bit mask + #define MANTISSA 0x007FFFFF // Mantissa bit mask + #define EXPONENT 0x7F800000 // Exponent bit mask - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This macro describe the maximum number of possible encoding passes during the ! + ! entropy encoding stage. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #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 index 4451388..5d13a82 100755 --- a/include/library/private/tagtree.h +++ b/include/library/private/tagtree.h @@ -1,161 +1,94 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This file defines a tagtree procedure used to encode/decode two types of || +|| information found defining in a codeblock in specific quality layer: || +|| || +|| - The inclusion tag records if a codeblock has any contribution || +|| to a quality layer. || +|| - The number of leading bitplanes that are not significant/only || +|| populated by zero bits. || +|| || +|| For more information on the encoding/decoding process please refere to JPEG2000 || +|| by D. S. Taubman and M. W. Marcellin (p. 384). || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #ifndef TAGTREE_H #define TAGTREE_H + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + #include "types.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); + /************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************/ + void kill_tagtree (bwc_tagtree *const tagtree); + //==========|==========================|======================|======|=======|==================== + uchar initialize_tagtree (bwc_tagtree *const tagtree, + uint64 const leafsX, + uint64 const leafsY, + uint64 const leafsZ, + uint64 const leafsTS); + //==========|==========================|======================|======|=======|==================== + uint16 tagtree_get_value (bwc_tagtree const *const tagtree, + uint64 const leaf_index); + //==========|==========================|======================|======|=======|==================== + void tagtree_set_value (bwc_tagtree *const tagtree, + uint64 const leaf_index, + uint16 const value); + //==========|==========================|======================|======|=======|==================== + void encode_tagtree (bwc_tagtree *const tagtree, + bwc_stream *const stream, + uint32 const threshold, + uint32 const leaf_index, + uchar const estimate); + //==========|==========================|======================|======|=======|==================== + uchar decode_tagtree (bwc_tagtree *const tagtree, + bwc_stream *const stream, + uint32 const threshold, + uint32 const leaf_index); #endif \ No newline at end of file diff --git a/include/library/private/tier1.h b/include/library/private/tier1.h index 7526caa..0a9c446 100755 --- a/include/library/private/tier1.h +++ b/include/library/private/tier1.h @@ -1,153 +1,160 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This file describes a set of functions that can be used to de-/encode bwc || +|| codeblocks described by the bwc_field structure according to the embedded block || +|| coding paradigm described by the JPEG 2000 standard. For more information please || +|| refere to JPEG2000 by D. S. Taubman and M. W. Marcellin. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #ifndef TIER1_H #define TIER1_H + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + #include "types.h" - /************************************************************************************************************\ - || _ _ _ ____ _ _ _ ___ ____ || - || | |\ | | | | | | \ |___ || - || | | \| |___ |___ |__| |__/ |___ || - || || - \************************************************************************************************************/ - #include "types.h" + /************************************************************************************************\ + || ___ ____ ____ ____ _ _ _ ____ ___ ___ _ _ ___ ____ ____ || + || | \ |___ |__/ |__/ | | | |___ | \ | \_/ |__] |___ [__ || + || |__/ |___ | \ | \ | \/ |___ |__/ | | | |___ ___] || + || || + \************************************************************************************************/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds the sign (xi), bitfield (bit) and state (delta, sigma and pi) ! + ! information for four vertically adjacent samples for easy access during the ! + ! entropy encoding stage. Here, the delayed significance is set once the first bit ! + ! is encoded during the magnitude refinement pass, while the significance state ! + ! sigma is set once the first non-zero bit is encoded for a specific sample. ! + ! The stripe_* pointers are used to store the address of the left(l), upper(u), ! + ! right(r) and lower(d) neighbour of a specific stripe for easy access. To ! + ! facilitate distortion estimation the magnitude of the wavelet coefficients is ! + ! stored in an appropriate sample array. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + typedef struct stripe + { + uint64 *sample; // Wavelet coeff. for two adjacent stripes. - /************************************************************************************************************\ - || _ _ ____ ____ ____ ____ ____ || - || |\/| |__| | |__/ | | [__ || - || | | | | |___ | \ |__| ___] || - || || - \************************************************************************************************************/ - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 + uint8 delta; // Delayed sig. for two adjacent stripes. + uint8 sigma; // Significance for two adjacent stripes. + uint8 pi; // Coding pass membership for adj. stripes. - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 + uint8 codingpass; // Last decoded coding pass. - #define DWT_5X3_G0 0.75f - #define DWT_5X3_G1 -0.25f - #define DWT_5X3_G2 -0.125f + uint8 bitplane; // Last decoded bitplane. + uint8 *bit; // Bitplanes for vertically adj. stripes. + uint8 xi; // Wavelet coef. sign bit for adj. stripes. - /************************************************************************************************************\ - || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || - || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || - || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || - || || - \************************************************************************************************************/ - /*----------------------------------------------------------------------------------------------------------*\ - ! TYPE NAME: Template ! - ! ----------- ! - ! ! - ! DESCRIPTION: ! - ! ------------ ! - ! DESCRIPTION NEEDED ! - ! ! - \*----------------------------------------------------------------------------------------------------------*/ - uchar - t1_encode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const parameter); + struct stripe *stripe_u; // Upper stripe. + struct stripe *stripe_r; // Right stripe. + struct stripe *stripe_d; // Lower stripe. + struct stripe *stripe_l; // Left stripe. + } bwc_coder_stripe; - uchar - t1_decode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const parameter); + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure accumulates all necessary structures used to (de-)compress a ! + ! codeblock of wavelet coefficients. The spatial and temporal dimension of the ! + ! codeblock is defined by its width, height and number of slices (depth * dt). The ! + ! codeblock itself is subdivided into so-called stripes that represent 4 vertically ! + ! adjacent coefficients. The parameter no_full_stripes stores overnumber of full ! + ! stripes present in one slice. ! + ! The look-up table sig2context is used to determine the coding context of a current ! + ! bit according to its significance context within the codeblock bitplane. The ! + ! look-up table is specific to a certain highband and is set accordingly. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + typedef struct + { + uchar resilience; // Flag signaling error resilience. + + uint64 no_full_stripe; // Number of full, vert. adjacent stripes. + uint64 width, height; // Codeblock width and height. + uint64 no_slice; // Number of slices in the spec. codeblock. + + uint8 const *sig2context; // Signifance-to-context loop-up table. + bwc_bit_coder *bitcoder; // BWC bitcoder. + + bwc_coder_stripe *data; // BWC coder stripe. + + uint64 buff_size; // Size of packed stream. + uint64 buff_incr; // Increment for packed stream assembly. + uchar *compressed; // Compressed data chunck. + } bwc_coder; + + /************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************/ + uchar t1_encode (bwc_field *const field, + uint16 const parID); + //==========|==========================|======================|======|=======|==================== + uchar t1_decode (bwc_field *const field, + uint16 const parID); #endif \ No newline at end of file diff --git a/include/library/private/tier2.h b/include/library/private/tier2.h index d853bfe..b662841 100755 --- a/include/library/private/tier2.h +++ b/include/library/private/tier2.h @@ -1,133 +1,84 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This file describes a set of functions that can be used to de-/encode bwc || +|| codeblocks described by the bwc_field structure according to the embedded block || +|| coding paradigm described by the JPEG 2000 standard. For more information please || +|| refere to JPEG2000 by D. S. Taubman and M. W. Marcellin. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #ifndef TIER2_H #define TIER2_H + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + #include "types.h" - /************************************************************************************************************\ - || _ _ _ ____ _ _ _ ___ ____ || - || | |\ | | | | | | \ |___ || - || | | \| |___ |___ |__| |__/ |___ || - || || - \************************************************************************************************************/ - #include "types.h" + /************************************************************************************************\ + || _ _ ____ ____ ____ ____ ____ || + || |\/| |__| | |__/ | | [__ || + || | | | | |___ | \ |__| ___] || + || || + \************************************************************************************************/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! Definition of the initial codestream packet header size. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define PACKET_HEADER_SIZE 512 - /************************************************************************************************************\ - || _ _ ____ ____ ____ ____ ____ || - || |\/| |__| | |__/ | | [__ || - || | | | | |___ | \ |__| ___] || - || || - \************************************************************************************************************/ - /*----------------------------------------------------------------------------------------------------------*\ - ! 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); + /************************************************************************************************\ + || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || + || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || + || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || + || || + \************************************************************************************************/ + uchar t2_encode (bwc_field *const field); + //==========|==========================|======================|======|=======|==================== + uchar parse_packet (bwc_field *const field, + 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 index e41fa35..7766997 100755 --- a/include/library/private/types.h +++ b/include/library/private/types.h @@ -1,1805 +1,1042 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This header defines a set of derrived types that are used to describe and || +|| instruct the bwc (de-)compression library. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #ifndef BWC_TYPES_H #define BWC_TYPES_H + /************************************************************************************************\ + || _ _ _ ____ _ _ _ ___ ____ || + || | |\ | | | | | | \ |___ || + || | | \| |___ |___ |__| |__/ |___ || + || || + \************************************************************************************************/ + #include - #include - /************************************************************************************************************\ - || _ _ _ ____ _ _ _ ___ ____ || - || | |\ | | | | | | \ |___ || - || | | \| |___ |___ |__| |__/ |___ || - || || - \************************************************************************************************************/ - #ifdef BWC_SINGLE_PRECISION - #include "prim_types_single.h" - #else - #include "prim_types_double.h" - #endif + #ifdef BWC_SINGLE_PRECISION + #include "prim_types_single.h" + #else + #include "prim_types_double.h" + #endif - #include "constants.h" - #include "mq_types.h" + #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; + /************************************************************************************************\ + || ___ ____ ____ ____ _ _ _ ____ ___ ___ _ _ ___ ____ ____ || + || | \ |___ |__/ |__/ | | | |___ | \ | \_/ |__] |___ [__ || + || |__/ |___ | \ | \ | \/ |___ |__/ | | | |___ ___] || + || || + \************************************************************************************************/ + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This union describes a simple data type used to store a single sample of a ! + ! numerical dataset. The union allows access to the raw bit representation of the ! + ! data sample. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef union + { + bwc_raw raw; // Raw data sample access. + bwc_float f; // IEEE 754 representation of a data sample. + } 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; + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure is used to store the metadata and boy of a packed stream. Tile and ! + ! paramter index can be supplied to uniquely identify the stream. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 size; // Size of packed 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; + uint64 tile; // Tile Index. + uint8 param; // Parameter Index. - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + uchar *access; // Pointer used to parse packed stream. + uchar *memory; // Memory handle for the packed stream. + } bwc_packed_stream; - /*----------------------------------------------------------------------------------------------------------*\ - | ___ ____ ____ ___ ____ ____ ____ | - | | |__| | __ | |__/ |___ |___ | - | | | | |__] | | \ |___ |___ | - | | - \*----------------------------------------------------------------------------------------------------------*/ - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure is used to read/assemble a packed codestream during coding. The ! + ! byte buffer is flushed to the packed stream as soon as the a single byte has been ! + ! assembled. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uchar error; // Error flag used during streaming process. - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + uint64 L; // Number of bytes written to/from stream. + uint64 Lmax; // Size of packed stream. + uint64 size_incr; // Size increment used for stream assembly. - /*----------------------------------------------------------------------------------------------------------*\ - | ___ ____ ___ ____ ____ ____ ___ | - | | \ |__| | |__| [__ |___ | | - | |__/ | | | | | ___] |___ | | - | | - \*----------------------------------------------------------------------------------------------------------*/ - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + uint8 T; // Byte buffer. + int8 t; // Byte buffer counter. - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + uchar *memory; // Memory handle for packed stream chunck. + } bwc_stream; - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure defines a single tagtree node which stores the node value (tag), ! + ! node threshold as well as the address of the parent node. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct node + { + uint64 index; // Index of current node. - struct codestream + uint16 value; // Tagtree node value. + uint16 threshold; // Tagtree node threshold. + + struct node* parent; // Parent of current node. + } bwc_tagtree_node; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure defines a tagtree instance with spatial and temporal leaves that ! + ! can be used to encode codeblock tags - e.g. number of significant bitplanes - to ! + ! efficiently store them in the compressed codestream. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 leavesX, leavesY; // Number of spatial tagtree leafs. + uint64 leavesZ, leavesTS; // Number of temporal tagtree leafs. + + bwc_tagtree_node *nodes; // Pointer to the tagtree nodes. + } bwc_tagtree; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure defines and stores all necessary data for a compressed codeblock. ! + ! The coding pass lengths and distortion rate arrays define the convex hull used for ! + ! during rate controlling. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 L[MAXIMUM_NO_PASSES]; // Coding pass lengths of an ecnoded block. + uint16 S[MAXIMUM_NO_PASSES + 1]; // Distortion rate of an encoded block. + + uint8 Kmsbs; // N.o. insignificant leading bitplanes. + uint8 K; // First significant bitplane. + + uint8 Z; // Number of coding passes generated. + + uchar *data; // Memory handle to compressed bitstream. + } bwc_encoded_blk; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! 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. The unique state ! + ! variables are used during length encoding both for quality layer estimation as ! + ! well as packet assembly. The cp_contr access pointer allows access to the memory ! + ! chunck employed to store the coding passes contributing to a specific quality ! + ! layer. The parameter K represents the most significant bitplane present in the ! + ! current codeblock. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint16 beta; // Codeblock unique state variable. + uint16 beta_est; // State variable used for ql estimation. + + uint16 K; // Codeblock spec. significant bitplane. + + int16 *memory; // Coding pass contribution to q. layer. + int16 *cp_contr; // Coding pass contribution access pointer. + } bwc_cblk_ctrl; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure is used to store the start and end points as well as the index for ! + ! a specific codeblock. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint32 idx; // Codeblock index w.r.t. precinct. + + uint64 X0, Y0, Z0, TS0; // Codeblock starting point. + uint64 X1, Y1, Z1, TS1; // Codeblock end point. + } bwc_cblk_inf; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the necessary parameters used to define and control a bwc ! + ! codeblock. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_cblk_inf info; // Codeblock info structure. + bwc_cblk_ctrl control; // Codeblock control structure. + bwc_encoded_blk encoded_block; // Encoded block structure. + } bwc_codeblock; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! 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. The number ! + ! codeblocks are stored for all spatial and temporal dimensions as well as for the ! + ! entire precinct. The two tagtrees are employed to record specific properties of ! + ! the underlying data that is to be compressed. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 numCodeblocks_a; // Number of allocated codeblocks. + uint64 numCodeblocks; // Number of codeblocks w.r.t res. level. + + uint16 numCbX, numCbY; // Number of spaatial codeblocks. + uint16 numCbZ, numCbTS; // Number of temporal codeblocks. + + bwc_tagtree tag_inclusion; // Quality layer contribution tagtree. + bwc_tagtree tag_msbs; // Most significant bit-planes tagtree. + } bwc_prec_ctrl; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure is used to store the start and end points for the current precinct. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint32 X0, Y0, Z0, TS0; // Precinct starting point. + uint32 X1, Y1, Z1, TS1; // Precinct end point. + } bwc_prec_inf; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the necessary parameters used to define and control a bwc ! + ! precinct. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_prec_inf info; // Precinct info structure. + bwc_prec_ctrl control; // Precinct control structure. + bwc_codeblock *codeblock; // Precinct specific codeblocks. + } bwc_precinct; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! 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. The highband flag ! + ! is used to identify the type of highband a specific wavelet band belongs to (e.g. ! + ! HHHH). The quantization step size mantissa and exponent for a subband is stored ! + ! alongside its actual value as well as the effective step size that is applied to ! + ! the wavelet coefficients. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uchar highband; // Current wavelet highband type + + uint16 Kmax; // Dynamic ranger after transformation. + + uint16 qt_mantissa; // Quantization step size mantissa. + uint8 qt_exponent; // Quantization step size exponent. + + bwc_float qt_eff_step_size; // Effective quantization step size. + bwc_float qt_step_size; // Quantization step size. + } bwc_subb_ctrl; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure is used to store the start and end points as well as the energy ! + ! gain factor of the wavelet decomposition that has been applied to the subband data ! + ! samples during transformation. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 X0, Y0, Z0, TS0; // Subband starting point. + uint64 X1, Y1, Z1, TS1; // Subband end point. + + bwc_float dwt_gain; // Energy gain factor for the cur. subband. + } bwc_subb_inf; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the necessary parameters used to define and control a bwc ! + ! subband. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_subb_inf info; // Subband info structure. + bwc_subb_ctrl control; // Subband control structure. + + bwc_precinct *precinct; // Subband specific precincts. + } bwc_subband; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the parameters used to assemble a codestream packet. The ! + ! indices p, c, l and r are represent the precinct, parameter, quality layer and ! + ! resolution level a packet belongs to and are used for codestream assembly. The ! + ! flag e records if any codeblock contributions are available for a specific ! + ! packets. ! + ! ! + ! STRUCT: ! + ! ------- ! + ! Name Description ! + ! ---- ----------- ! + ! e - Indicator of codeblock contributions ! + ! present in current packet. ! + ! ! + ! size - Size of the codestream packet. ! + ! ! + ! pr - Precinct index used to position ! + ! current packet in codestream. ! + ! ! + ! p, l, r - Param., Quality Layer and Resolution ! + ! codestream position marker. ! + ! ! + ! DEVELOPMENT HISTORY: ! + ! -------------------- ! + ! ! + ! Date Author Release Description ! + ! ---- ------ ------- ----------- ! + ! 23.10.2017 Patrick Vogler V 0.1.0 Struct created. ! + ! 15.04.2020 Patrick Vogler V 0.1.0 Clean up. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_packed_stream header; // Packed stream header. + bwc_packed_stream body; // Packed stream body. + uint8 e; // Indicator for packet cb. contributions. + + uint32 size; // Codestream packet size. + + uint32 pr; // Position of current packet in codestream. + uint8 p, l, r; // Position according to. + } bwc_packet; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! 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. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint16 numPX, numPY; // Spatial number of precincts. + uint16 numPZ, numPTS; // Temporal number of precincts. + + uint8 rcbX, rcbY; // Real spatial codeblock size. + uint8 rcbZ, rcbTS; // Real temporal codeblock size. + + uint64 numPrecincts_a; // Number of allocated precincts. + uint8 numSubbands_a; // Number of allocated resolution levels. + + uint64 numPrecincts; // Number of precincts in resolution level. + uint8 numSubbands; // Number of subbands in resolution leve. + } bwc_res_ctrl; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure is used to store the name, start and end points of the current ! + ! resolution level. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 X0, Y0, Z0, TS0; // Resolution level starting point. + uint64 X1, Y1, Z1, TS1; // Resolution level end point. + } bwc_res_inf; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the necessary parameters used to define and control a bwc ! + ! resolution level. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_res_inf info; // Resolution level info structure. + bwc_res_ctrl control; // Resolution level control structure. + + bwc_subband *subband; + bwc_packet *packet; + } bwc_resolution; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure is used to directly access the parameter codeblocks during entropy ! + ! (de-)encoding to facilitate shared memory parallelization. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_codeblock *codeblock; // Access to all tile param. codeblocks. + bwc_precinct *precinct; // Access to all tile param. precincts. + bwc_subband *subband; // Access to all tile param. subbands. + } bwc_cblk_access; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the control parameters for the current tile param. used ! + ! to instruct the bwc codec to (de)compress a floating point array. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 numCodeblocks; // Number of codeblocks in the tile param. + + uint8 sampX, sampY; // Spatial sub-sampling values. + uint8 sampZ, sampTS; // Temporal sub-sampling values. + + bwc_float alpha, beta; // Parameters used to normalize data-sample. + } bwc_param_ctrl; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure is used to store the name, start and end points as well as the ! + ! overall size of a parameter tile. Furthermore, the minimum and maximum sample ! + ! values for the current parameter tile are stored. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + char *name; // Parameter name. + + uint64 X0, Y0, Z0, TS0; // Tile parameter starting point. + uint64 X1, Y1, Z1, TS1; // Tile parameter end point. + + uint8 precision; // Tile parameter precision. + + bwc_float min, max; // Min./Max. values of tile parameter. + } bwc_param_inf; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the necessary parameters used to define and control the ! + ! (de)compression of a bwc tile parameter. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 size; // Size of the bwc_float data structure. + bwc_float *data; // Tile parameter values. + + bwc_param_inf info; // Parameter info structure. + bwc_param_ctrl control; // Parameter control structure. + + bwc_resolution *resolution; // Tile parameter specific resol. levels. + + bwc_cblk_access *access; // Access to all tile param. codeblocks. + } bwc_parameter; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! 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. ! + ! The slope_min and slope_max values represent the minimum and maximum distortion ! + ! rates for the compressed data-samples of a specific tile. These values define the ! + ! distortion-bitrate convex hull used for rate control. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint16 slope_min, slope_max; // Min./Max. values for the convec hull slp. + + uint64 numPackets; // Number of packets assembled for tile. + uint32 numPrecincts; // Number of precincts assembled for tile. + } bwc_tile_ctrl; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure is used to store the start and end points of the tile as well as ! + ! its overall size. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint32 index; // Unique tile index. + + uint64 X0, Y0, Z0, TS0; // Tile starting point. + uint64 X1, Y1, Z1, TS1; // Tile end point. + } bwc_tile_inf; + + /*------------------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This structure holds all the necessary parameters used to define and control the ! + ! (de)compression of a bwc tile. The packet_sequence pointer array is used to store ! + ! the bitstream packet memory hanldes of the underlying tile in a predefined ! + ! sequence according to the bwc_progression_ord parameter. The pointer array is ! + ! employed during codestream assembly. ! + ! ! + \*------------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! DESCRIPTION NEEDED ! + ! | | ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + bwc_tile_inf *info; // Tile info structure. + bwc_tile_ctrl control; // Tile control structure. + + bwc_parameter *parameter; // Tile specific parameter structure. + bwc_packet **packet_sequence; // Tile specific packet sequence. + } bwc_tile; + + + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! | | ! + ! This structure holds all the global control parameters, including the tile, ! + ! precinct and codeblock sizes as well as the global number of tiles, used to ! + ! instruct the bwc codec to (de)compress a floating point array. ! + ! The number of decompositions (numDecompX etc.) define the number of times the ! + ! selected wavelet filter (kernelX etc.) is applied alongside each spatial and ! + ! temporal direction. The global number of decomposition levels is stored in the ! + ! appropriate variable. ! + ! The parameters qt_mantissa and qt_exponent define the mantissa and exponent of ! + ! the global quantization step size appropriate for the specified number of ! + ! wavelet decomposition levels. The quantization_style signals if the quantization ! + ! step size for the subsequent subbands should be derrived from the global ! + ! parameter, or not. The variable Qm represents the dynamic range of the ! + ! float-to-fixed point transformation employed pre-compression. ! + ! The bitrate array stores up to 10 bitrate values - average bits per datasample - ! + ! that define the codestream quality layers. The largest bitrates defines the ! + ! compression ratio, while the total number of defined bitrates represent the ! + ! number of (quality)layers. The parameter use_layer stores the index of the ! + ! quality layer that is used during decompression. The progression order defines ! + ! the packet sequence as they will appear in the compressed codestream. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint16 CSsgc; // Flag signaling user control variable. + uchar resilience; // Flag signalling error resilience. + + uint64 tileSizeX, tileSizeY; // Spatial tile size. + uint64 tileSizeZ, tileSizeTS; // Temporal tile size. + + uint64 numTilesX, numTilesY; // Spatial number of tiles. + uint64 numTilesZ, numTilesTS; // Temporal number of tiles. + uint64 numTiles; // Global number of tiles. + + uint64 main_header_size; // Main codestream header size. + uint64 *packed_tile_size; // Size of compressed and packet stream. + + uint8 precSizeX, precSizeY; // Spatial precinct size. + uint8 precSizeZ, precSizeTS; // Temporal precinct size. + + uint8 cbX, cbY; // Spatial codeblock size. + uint8 cbZ, cbTS; // Temporal codeblock size. + + bwc_dwt_filter KernelX, KernelY; // Spatial wavelet kernels. + bwc_dwt_filter KernelZ, KernelTS; // Temporal wavelet kernels. + + uint8 numDecompX, numDecompY; // Number of wavelet decompositions ... + uint8 numDecompZ, numDecompTS; // ... for each of the four dimensions. + uint8 numDecomp; // Maximum No. wavelet decompositions. + + uint32 qt_exponent, qt_mantissa; // Global qunatization exponent/mantissa. + uint8 Qm; // Q number format range (m). + + float bitrate[10]; // Quality layers defined by bitrate. + float compression_estimation; // Estimation of compression performance. + + uint8 numLayers; // Number of quality layers. + uint8 use_layer; // Quality layer used for decompression. + + uint8 numThreads; // Number of OMP Threads. + + bwc_quant_st quantization_style; // Quantization style. + bwc_prog_ord progression; // Packet progression order. + } bwc_gl_ctrl; + + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This structure defines a linked list which stores the size, index, bit precision, ! + ! sampling factor and the dimension for which the sampling is active for a user ! + ! defined parameter. The string name is used to store the parameter name supplied ! + ! by the function caller. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct opt + { + char name[24]; // Parameter name. + uint8 id; // Parameter index. + + uint64 size; // Parameter size after sub-sampling. + uint8 precision; // Parameter precision. + + uint8 sample; // Sub-sampling factor. + uchar dim; // Dimensions sub-sampling is applied to. + + struct opt *next; // Next element in linked-list. + struct opt *root; // Linked-list root. + } bwc_cmd_opts_ll; + + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This structure holds all the global information of an uncompressed data set ! + ! including its spatial and temporal dimensions, number of parameters, file ! + ! extension and parameter information as well as the codec precision. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + uint64 nX, nY, nZ; // Spatial size of uncompressed data-set. + uint64 nTS; // Temp. size of uncompressed data-set. + + uint8 numParams; // Number of parameters. + + uint8 codec_prec; // Encoder/decoder bit precision. + char file_ext[20]; // Uncompressed data set file extension. + + bwc_cmd_opts_ll *parameter; // Command options linked-list. + } bwc_gl_inf; + + + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor ! + ! incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis ! + ! nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ! + ! Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu ! + ! fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in ! + ! culpa qui officia deserunt mollit anim id est laborum. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This structure holds all the necessary parameters defining and controling a bwc ! + ! (de-)compression run. ! + ! ! + ! The meter structure is used to store measurements, including important time ! + ! measurements, for a particular compression run. ! + ! ! + ! The memory structure is used to hold the global memory limit as well as to keep ! + ! track of a rough estimate of the codecs memory usage. ! + ! ! + ! The setup structure defines the dyadic decomposition structure of a bwc tile. It ! + ! is initialized once for every (de)compression run and needs to be reset before ! + ! (de)compression a specific bwc tile with the appropriate reset function. ! + ! ! + ! The codestream structure is used to store the bwc header and bitstream. If the ! + ! codestream is set to be streamed, the packed tile parameters is only used to ! + ! buffer the compressed tiles until they are written to or after they have been ! + ! read from a bwc file defined by the file pointer 'fp'. ! + ! ! + ! The data structure is used to store the numerical dataset. If it is set to be ! + ! streamed, the packed tile parameter is only used to buffer the dataset tiles ! + ! until they are written to or after they have been read from the file defined by ! + ! the file pointer 'fp'. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct bwc_field_t bwc_field; + struct bwc_field_t + { + uchar flag; // Flag used for error handling. + + bwc_gl_inf info; // Gloabal info structure + bwc_gl_ctrl control; // Global control structure + + struct meter + { + double bpd; // Average bits per datapoint. + double cpr; // Compression ratio + double css; // Codestream size. + + struct time { - bwc_packed_stream *data; - bwc_packed_stream *aux; - bwc_packed_stream *com; - }codestream; + double ttl; // Total compression time. - struct field + double cpy; // Total time used copying data. + double nrm; // Total time used normalizing data. + + double wav; // Total time used for wavelet transform. + double ent; // Total time used for entropy encoding. + double ass; // Total codestream assembly time. + } time; + } meter; + + struct memory + { + uint64 limit; // User specified memory usage limit. + + struct usage { - double *d; - float *f; - }field; + uint64 setup; // Setup structure memory usage. + uint64 codestream; // Memory usage of stored codestream. + uint64 data; // Memory usage of stored uncompr. data. - struct file + uint64 stat; // Additional memory usage. + } usage; + } memory; + + struct setup + { + uchar flag; // Flag signalling compr./decompr. + + bwc_tile_inf *canvas; // Array of all tile info structures. + bwc_tile tile; // Structure defining bwc tile. + + bwc_packed_stream working_buffer; // Current data chunck access pointer. + } setup; + + struct codestream + { + uchar flag; // Flag signaling the codestream setup. + FILE *fp; // File Pointer to compressed data-set. + + struct header { - FILE *fp; - uint64 *d_root; - uint64 *f_root; - }file; - } bwc_data; + bwc_packed_stream sgi; // Global information codestream block. + bwc_packed_stream sgc; // Global control codestream block. + bwc_packed_stream sgr; // Global register codestream block. - /*----------------------------------------------------------------------------------------------------------*\ - | ____ ____ _ _ ___ ____ ____ ____ ____ _ ____ _ _ | - | | | | |\/| |__] |__/ |___ [__ [__ | | | |\ | | - | |___ |__| | | | | \ |___ ___] ___] | |__| | \| | - | | - \*----------------------------------------------------------------------------------------------------------*/ - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + bwc_packed_stream aux; // Auxiliary info. codestream block. + bwc_packed_stream com; // Com codestream block. + } header; - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + uint64 limit; // Generated Codestream memory limit. + uint64 count; // Number of generated codestream chunks. + uint64 idx; // Current generated codestream chunk. - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + bwc_packed_stream *body; // Array of generated codestream chunks. + } codestream; - /*----------------------------------------------------------------------------------------------------------*\ - ! 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 data + { + uchar flag; // Flag signaling data structure set-up. + FILE *fp; // File point to uncompr. data-set. - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + uint64 limit; // Memory limit for codestream chunks. + uint64 count; // Number of ingested codestream chunks. + uint64 idx; // Current ingested codestream chunk. - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + bwc_packed_stream *body; // Array of ingested codestream chunks. - /*----------------------------------------------------------------------------------------------------------*\ - ! 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; + void *util; // File type specific utility structure. + void (*free)(bwc_field*); // Function ptr used to free data struct. + uchar (*IO)(bwc_field*, // Function ptr used to read/write data. + uint64, + uint64, + uint8); + } data; + }; #endif \ No newline at end of file diff --git a/include/tools/bwccmdl.h b/include/tools/bwccmdl.h index be53e0b..92c9432 100644 --- a/include/tools/bwccmdl.h +++ b/include/tools/bwccmdl.h @@ -1,350 +1,102 @@ -/*====================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*====================================================================================================================*/ +/*================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| || +|| This is a simple command line tool that uses the Big Whoop library to (de) || +|| compress a 2- to 4-dimensional IEEE 754 floating point array. For further || +|| information use the --help (-h) argument in the command-line or consult the || +|| appropriate README file. || +|| || +|| -------------------------------------------------------------------------------------------- || +|| 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. || +|| || +\*================================================================================================*/ #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: ! + ! ------------ ! + ! ! + ! This macro removes a user supplied deliminator from a string: ! + ! ! + ! 9/9/7/2 -> 9 9 7 2. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define remove_deliminator(arg, end, delim) \ + { \ + for(end = arg; *end; end++) \ + *end = (*end == delim ? ' ' : *end); \ + } - /*------------------------------------------------------------------------------------------------------------------*\ - ! 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" + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These macros define minimum and maximum operators as well as an operator used ! + ! to evaluate the size of an array. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + #define MAX(x, y) (((x) < (y))?(y):(x)) // Returns maximum between two values + #define MIN(x, y) (((x) > (y))?(y):(x)) // Returns minimum between two values + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! These Constants define common error messages used throughout the bwc library. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ #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 index 489975e..316202c 100644 --- a/public_header.py +++ b/public_header.py @@ -1,54 +1,53 @@ -#*====================================================================================================================*# -#| |# -#| /$$$$$$$ /$$ /$$ /$$ /$$ |# -#| | $$__ $$|__/ | $$ /$ | $$| $$ |# -#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# -#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# -#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# -#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# -#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# -#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# -#| /$$ \ $$ | $$ |# -#| | $$$$$$/ | $$ |# -#| \______/ |__/ |# -#| |# -#| 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. |# -#| |# -#\====================================================================================================================/# +#*================================================================================================*# +#| |# +#| /$$$$$$$ /$$ /$$ /$$ /$$ |# +#| | $$__ $$|__/ | $$ /$ | $$| $$ |# +#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# +#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# +#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# +#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# +#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# +#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# +#| /$$ \ $$ | $$ |# +#| | $$$$$$/ | $$ |# +#| \______/ |__/ |# +#| |# +#| DESCRIPTION: |# +#| ------------ |# +#| |# +#| This file describes python script used to assemble the public header file for |# +#| the BigWhoop compression library. |# +#| |# +#| -------------------------------------------------------------------------------------------- |# +#| 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. |# +#| |# +#*================================================================================================*# +#**************************************************************************************************# +#| _ _ _ ___ ____ ____ ___ |# +#| | |\/| |__] | | |__/ | |# +#| | | | | |__| | \ | |# +#| |# +#**************************************************************************************************# from argparse import ArgumentParser from math import ceil, floor from pathlib import Path @@ -57,6 +56,20 @@ import os import re import sys +#-------------------------# +# DEFINE CONSTANTS: # +#-------------------------# +tab = " " +text_width = 100 +deliminator = tab + "/*" + (text_width - 4 - len(tab)) * "=" + "*/\n" +ubox = tab + "/" + (text_width - 2 - len(tab)) * "*" + "\\\n" +lbox = tab + "\\" + (text_width - 2 - len(tab)) * "*" + "/\n" +sbox = "||" + +#----------------------------------------------------------# +# Setup the argument parser for the public header script # +# and parse for the user defined OpenMP and Precision arg. # +#----------------------------------------------------------# parser = ArgumentParser(description='Public Header Assembly Script') parser.add_argument('-OMP', dest='OpenMP', action='store_const', const=True, default=False, @@ -67,220 +80,254 @@ parser.add_argument('-Single', dest='SinglePrecision', action='store_const', args = parser.parse_args() + +#----------------------------------------------------------# +# Setup the paths to the source and destination. # +#----------------------------------------------------------# 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') +if os.path.isdir(destination) == False: + os.mkdir(destination) +header_files = [f for f in os.listdir(source) if os.path.isfile(os.path.join(source, f))] +header_files.remove('prim_types_double.h') +header_files.remove('prim_types_single.h') +print(header_files) -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" - +#----------------------------------------------------------# +# Create the I/O stream and write the bwc file header. # +#----------------------------------------------------------# 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" +public_header.write("/*================================================================================================*\\\n" + "|| ||\n" + "|| /$$$$$$$ /$$ /$$ /$$ /$$ ||\n" + "|| | $$__ $$|__/ | $$ /$ | $$| $$ ||\n" + "|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ ||\n" + "|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ ||\n" + "|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ ||\n" + "|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ ||\n" + "|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ ||\n" + "|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ ||\n" + "|| /$$ \ $$ | $$ ||\n" + "|| | $$$$$$/ | $$ ||\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 ||\n" + "|| permitted provided 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 ||\n" + "|| materials provided with the distribution. ||\n" + "|| ||\n" + "|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS ||\n" + "|| OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ||\n" + "|| MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ||\n" + "|| COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ||\n" + "|| EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ||\n" + "|| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ||\n" + "|| 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, ||\n" + "|| EVEN IF 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) +#----------------------------------------------------------# +# Generate the necessary includes for the bwc.h file. # +#----------------------------------------------------------# +title_length = 31 -public_header.write(ubox + tab + "||" + lspaces * " " + "_ _ _ ____ _ _ _ ___ ____" + rspaces * " " + "||\n" + - tab + "||" + lspaces * " " + "| |\ | | | | | | \ |___" + rspaces * " " + "||\n" + - tab + "||" + lspaces * " " + "| | \| |___ |___ |__| |__/ |___" + rspaces * " " + "||\n" + - tab + "||" + (116 - len(tab)) * " " + "||\n" + lbox) +lspaces = ceil((text_width - 2*len(sbox) - title_length - len(tab))/2) +rspaces = floor((text_width - 2*len(sbox) - title_length - len(tab))/2) + +public_header.write(ubox + tab + sbox + lspaces * " " + "_ _ _ ____ _ _ _ ___ ____" + rspaces * " " + sbox + "\n" + + tab + sbox + lspaces * " " + "| |\ | | | | | | \ |___" + rspaces * " " + sbox + "\n" + + tab + sbox + lspaces * " " + "| | \| |___ |___ |__| |__/ |___" + rspaces * " " + sbox + "\n" + + tab + sbox + (text_width - 2*len(sbox) - 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) +#----------------------------------------------------------# +# Ingest primitive type definitions from the corresponding # +# header files according to the user specified precision. # +#----------------------------------------------------------# +title_length = 62 -public_header.write(ubox + tab + "||" + lspaces * " " + "___ ____ _ _ _ _ ___ _ _ _ ____ ___ _ _ ___ ____ ____" + rspaces * " " + "||\n" + - tab + "||" + lspaces * " " + "|__] |__/ | |\/| | | | | | |___ | \_/ |__] |___ [__ " + rspaces * " " + "||\n" + - tab + "||" + lspaces * " " + "| | \ | | | | | | \/ |___ | | | |___ ___]" + rspaces * " " + "||\n" + - tab + "||" + (116 - len(tab)) * " " + "||\n" + lbox) +lspaces = ceil((text_width - 2*len(sbox) - title_length - len(tab))/2) +rspaces = floor((text_width - 2*len(sbox) - title_length - len(tab))/2) + +public_header.write(ubox + tab + sbox + lspaces * " " + "___ ____ _ _ _ _ ___ _ _ _ ____ ___ _ _ ___ ____ ____" + rspaces * " " + "||\n" + + tab + sbox + lspaces * " " + "|__] |__/ | |\/| | | | | | |___ | \_/ |__] |___ [__ " + rspaces * " " + "||\n" + + tab + sbox + lspaces * " " + "| | \ | | | | | | \/ |___ | | | |___ ___]" + rspaces * " " + "||\n" + + tab + sbox + (text_width - 2*len(sbox) - len(tab)) * " " + "||\n" + lbox) if(args.SinglePrecision == True): file = "prim_types_single.h" else: file = "prim_types_double.h" -print_flag = 0 +print_flag = False 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 + print_flag = True public_header.write(line) f.close -lspaces = ceil((116 - 29 - len(tab))/2) -rspaces = floor((116 - 29 - len(tab))/2) +#----------------------------------------------------------# +# Ingest Macros with 'BWC_' prefix from all header files. # +#----------------------------------------------------------# +title_length = 29 -public_header.write(ubox + tab + "||" + lspaces * " " + "_ _ ____ ____ ____ ____ ____" + rspaces * " " + "||\n" + - tab + "||" + lspaces * " " + "|\/| |__| | |__/ | | [__ " + rspaces * " " + "||\n" + - tab + "||" + lspaces * " " + "| | | | |___ | \ |__| ___]" + rspaces * " " + "||\n" + - tab + "||" + (116 - len(tab)) * " " + "||\n" + lbox) +lspaces = ceil((text_width - 2*len(sbox) - title_length - len(tab))/2) +rspaces = floor((text_width - 2*len(sbox) - title_length - len(tab))/2) -with open(source.joinpath('prim_types_double.h')) as f: +public_header.write(ubox + tab + sbox + lspaces * " " + "_ _ ____ ____ ____ ____ ____" + rspaces * " " + "||\n" + + tab + sbox + lspaces * " " + "|\/| |__| | |__/ | | [__ " + rspaces * " " + "||\n" + + tab + sbox + lspaces * " " + "| | | | |___ | \ |__| ___]" + rspaces * " " + "||\n" + + tab + sbox + (text_width - 2*len(sbox) - len(tab)) * " " + "||\n" + lbox) + +with open(source.joinpath(file)) 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 + if("MAXIMUM_NO_PASSES" in line or + "PREC_BIT" in line): + if("//" in line): + public_header.write((line.split('/', 1)[0]).rstrip() + '\n') + else: + public_header.write(line) f.close -lspaces = ceil((116 - 42 - len(tab))/2) -rspaces = floor((116 - 42 - len(tab))/2) +printFlg = False +buff = "" +brktCnt = 0 -public_header.write(ubox + tab + "||" + lspaces * " " + "____ ____ _ _ ____ ___ ____ _ _ ___ ____" + rspaces * " " + "||\n" + - tab + "||" + lspaces * " " + "| | | |\ | [__ | |__| |\ | | [__ " + rspaces * " " + "||\n" + - tab + "||" + lspaces * " " + "|___ |__| | \| ___] | | | | \| | ___]" + rspaces * " " + "||\n" + - tab + "||" + (116 - len(tab)) * " " + "||\n" + lbox) +for file in header_files: + with open(source.joinpath(file)) as f: + for line in f: + if("BWC_" in line): + if("ifndef" in line): + next(f) + elif("#define" in line and line[len(line) - len(line.lstrip())] != "/"): + while True: + if("//" in line): + buff = buff + (line.split('/', 1)[0]).rstrip() + '\n' + else: + buff = buff + line + if("\\" not in line): + public_header.write(buff+"\n") + buff = "" + break + line = next(f) + f.close +public_header.write("\n") -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 +#----------------------------------------------------------# +# Ingest enums with 'bwc_' prefix from all header files # +# excluding prim_types_****.h. # +#----------------------------------------------------------# +title_length = 42 -lspaces = ceil((116 - 64 - len(tab))/2) -rspaces = floor((116 - 64 - len(tab))/2) +lspaces = ceil((text_width - 2*len(sbox) - title_length - len(tab))/2) +rspaces = floor((text_width - 2*len(sbox) - title_length - len(tab))/2) + +public_header.write(ubox + tab + sbox + lspaces * " " + "____ ____ _ _ ____ ___ ____ _ _ ___ ____" + rspaces * " " + "||\n" + + tab + sbox + lspaces * " " + "| | | |\ | [__ | |__| |\ | | [__ " + rspaces * " " + "||\n" + + tab + sbox + lspaces * " " + "|___ |__| | \| ___] | | | | \| | ___]" + rspaces * " " + "||\n" + + tab + sbox + (text_width - 2*len(sbox) - len(tab)) * " " + "||\n" + lbox) + +delimFlg = False +buff = "" + +for file in header_files: + with open(source.joinpath(file)) as f: + for line in f: + if("typedef enum" in line): + while True: + buff = buff + (line.split('/', 1)[0]).rstrip() + '\n' + if("}" in line and ";" in line): + if("bwc_" in line): + if(delimFlg == True): + public_header.write(deliminator) + public_header.write(buff) + delimFlg = True + buff = "" + break + line = next(f) + f.close + +#----------------------------------------------------------# +# Ingest derived types with 'bwc_' prefix from all header # +# files excluding prim_types_****.h. # +#----------------------------------------------------------# +title_length = 64 + +lspaces = ceil((text_width - 2*len(sbox) - title_length - len(tab))/2) +rspaces = floor((text_width - 2*len(sbox) - title_length - 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) +public_header.write(ubox + tab + sbox + lspaces * " " + "___ ____ ____ ____ _ _ _ ____ ___ ___ _ _ ___ ____ ____" + rspaces * " " + "||\n" + + tab + sbox + lspaces * " " + "| \ |___ |__/ |__/ | | | |___ | \ | \_/ |__] |___ [__ " + rspaces * " " + "||\n" + + tab + sbox + lspaces * " " + "|__/ |___ | \ | \ | \/ |___ |__/ | | | |___ ___]" + rspaces * " " + "||\n" + + tab + sbox + (text_width - 2*len(sbox) - len(tab)) * " " + "||\n" + lbox) printFlg = False delimFlg = False preProcFlg = False -preProc = "" buff = "" brktCnt = 0 -for file in ["mq_types.h", "types.h"]: +for file in header_files: with open(source.joinpath(file)) as f: for line in f: - if("typedef" in line): + if("typedef struct" in line or + "typedef union" in line): + if("bwc_" in line): + printFlg = True 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 - + buff = buff + (line.split('/', 1)[0]).rstrip() + '\n' if("{" in line): brktCnt = brktCnt + 1 - if("}" in line): brktCnt = brktCnt - 1 if(brktCnt == 0): + if("bwc_" in line): + printFlg = True break line = next(f) - - if("bwc_" in line): - if(printFlg == True): - buff = deliminator + buff - else: - printFlg = True + if (printFlg == True): + if(delimFlg == True): + public_header.write(deliminator) public_header.write(buff) - + delimFlg = True buff = "" + f.close -lspaces = ceil((116 - 70 - len(tab))/2) -rspaces = floor((116 - 70 - len(tab))/2) +#----------------------------------------------------------# +# Ingest public functions with 'bwc_' prefix from all # +# header files excluding prim_types_****.h. # +#----------------------------------------------------------# +title_length = 70 -public_header.write("\n" + ubox + tab + "||" + lspaces * " " + "___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____" + rspaces * " " + "||\n" + - tab + "||" + lspaces * " " + "|__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ " + rspaces * " " + "||\n" + - tab + "||" + lspaces * " " + "| |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___]" + rspaces * " " + "||\n" + - tab + "||" + (116 - len(tab)) * " " + "||\n" + lbox) +lspaces = ceil((text_width - 2*len(sbox) - title_length - len(tab))/2) +rspaces = floor((text_width - 2*len(sbox) - title_length - len(tab))/2) + +public_header.write("\n" + ubox + tab + sbox + lspaces * " " + "___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____" + rspaces * " " + "||\n" + + tab + sbox + lspaces * " " + "|__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ " + rspaces * " " + "||\n" + + tab + sbox + lspaces * " " + "| |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___]" + rspaces * " " + "||\n" + + tab + sbox + (text_width - 2*len(sbox) - len(tab)) * " " + "||\n" + lbox) files = os.listdir("include/library/private") printFlg = False @@ -291,27 +338,16 @@ 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("#if defined" in line): + line = next(f) if("(" in line): - tmp = line[0:line.index('(')] + tmp = line[0:line.index('(')].strip() tmp = tmp[tmp.rfind(' '):-1] else: tmp = "" - if("bwc_" in tmp and "!" not in line): - if("/*" in buff or "*/" in buff): + if("bwc_" in tmp and "!" not in line and "#if" not in line): + if("/*" in buff or "*/" in buff or "//" in buff): buff = "" - else: - buff = buff[ltab:len(buff)] if(print_flag == True): buff = deliminator + buff diff --git a/src/interfaces/python/bwc.py b/src/interfaces/python/bwc.py index 474dc87..3e169bd 100644 --- a/src/interfaces/python/bwc.py +++ b/src/interfaces/python/bwc.py @@ -1,93 +1,65 @@ -#/=====================================================================================================================\# -#| |# -#| /$$$$$$$ /$$ /$$ /$$ /$$ |# -#| | $$__ $$|__/ | $$ /$ | $$| $$ |# -#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# -#! | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# -#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# -#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# -#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# -#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# -#| /$$ \ $$ | $$ |# -#| | $$$$$$/ | $$ |# -#| \______/ |__/ |# -#| |# -#| 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. |# -#| |# -#\=====================================================================================================================/# -#/=====================================================================================================================\# -#| _ _ _ ____ _ _ _ ___ ____ |# -#| | |\ | | | | | | \ |___ |# -#| | | \| |___ |___ |__| |__/ |___ |# -#| |# -#\=====================================================================================================================/# +#*================================================================================================*# +#| |# +#| /$$$$$$$ /$$ /$$ /$$ /$$ |# +#| | $$__ $$|__/ | $$ /$ | $$| $$ |# +#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# +#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# +#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# +#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# +#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# +#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# +#| /$$ \ $$ | $$ |# +#| | $$$$$$/ | $$ |# +#| \______/ |__/ |# +#| |# +#| DESCRIPTION: |# +#| ------------ |# +#| |# +#| This file defines a Python interface for the Big Whoop compression library. |# +#| |# +#| -------------------------------------------------------------------------------------------- |# +#| 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. |# +#| |# +#*================================================================================================*# +#**************************************************************************************************# +#| _ _ _ ____ _ _ _ ___ ____ |# +#| | |\ | | | | | | \ |___ |# +#| | | \| |___ |___ |__| |__/ |___ |# +#| |# +#**************************************************************************************************# import ctypes from numpy.ctypeslib import ndpointer from enum import Enum -libbwc = ctypes.cdll.LoadLibrary("../../../lib/libbwc.so") +libbwc = ctypes.cdll.LoadLibrary("../lib/libbwc.so") -#/=====================================================================================================================\# -#| ____ ____ _ _ ____ ___ ____ _ _ ___ ____ |# -#| | | | |\ | [__ | |__| |\ | | [__ |# -#| |___ |__| | \| ___] | | | | \| | ___] |# -#| |# -#\=====================================================================================================================/# +#**************************************************************************************************# +#| ____ ____ _ _ ____ ___ ____ _ _ ___ ____ |# +#| | | | |\ | [__ | |__| |\ | | [__ |# +#| |___ |__| | \| ___] | | | | \| | ___] |# +#| |# +#**************************************************************************************************# class _const(): class DWT(Enum): CDF_9_7 = 0 @@ -106,116 +78,140 @@ class _const(): 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 +#**************************************************************************************************# +#| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ |# +#| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ |# +#| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] |# +#| |# +#**************************************************************************************************# +def create_field(): + fun = libbwc.bwc_create_field 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.argtypes = None + return ctypes.c_void_p(fun()) +#==================================================================================================# +def free_field(field): + fun = libbwc.bwc_free_field 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 +#==================================================================================================# +def add_param(field, name, sample, dim, precision): + fun = libbwc.bwc_add_param 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) -#=======================================================================================================================# + fun.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int16, ctypes.c_int8, ctypes.c_int8] + fun(field, name.encode('utf-8'), sample, dim, precision) +#==================================================================================================# 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.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_kernels(field, KernelX, KernelY, KernelZ, KernelTS): + fun = libbwc.bwc_set_kernels + fun.restype = None + fun.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int] + fun(field, KernelX, KernelY, KernelZ, KernelTS) +#==================================================================================================# +def set_decomp(field, KernelX, KernelY, KernelZ, KernelTS): + 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, numDecompX, numDecompY, numDecompZ, numDecompTS) +#==================================================================================================# 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 +#==================================================================================================# +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_progression(field, progression): + fun = libbwc.bwc_set_progression + fun.restype = None + fun.argtypes = [ctypes.c_void_p, ctypes.c_int] + fun(field, progression) +#==================================================================================================# +def set_error_resilience(field): + fun = libbwc.bwc_set_error_resilience + fun.restype = None + fun.argtypes = [ctypes.c_void_p] + fun(field) +#==================================================================================================# +def set_quantization_style(field, quantization_style): + fun = libbwc.bwc_set_quant_style + fun.restype = None + fun.argtypes = [ctypes.c_void_p, ctypes.c_int] + fun(field, quantization_style) +#==================================================================================================# +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_quantization_step_size(field, delta): + fun = libbwc.bwc_set_quant_step_size + fun.restype = None + fun.argtypes = [ctypes.c_void_p, ctypes.c_double] + fun(field, delta) +#==================================================================================================# +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_memory_limit(field, limit): + fun = libbwc.bwc_set_memory_limit 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(field, limit.encode('utf-8')) +#==================================================================================================# +def open_file(field, filename, mode): + fun = libbwc.bwc_open_file + + fun.restype = ctypes.c_int8 + fun.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_char_p] + + res = fun(field, filename.encode('utf-8'), mode.encode('utf-8')) + if res == 1: + raise Exception() +#==================================================================================================# +def load_file(field, filename): + fun = libbwc.bwc_load_file + + fun.restype = ctypes.c_int8 + fun.argtypes = [ctypes.c_void_p, ctypes.c_char_p] + + res = fun(field, filename.encode('utf-8')) + if res == 1: + raise Exception() +#==================================================================================================# +def compress(field, rate_control): 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.restype = ctypes.c_int8 + fun.argtypes = [ctypes.c_void_p, ctypes.c_char_p] + + res = fun(field, rate_control.encode('utf-8')) + if res == 1: + raise Exception() +#==================================================================================================# +def decompress(field, layer): 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 + + fun.restype = ctypes.c_int8 + fun.argtypes = [ctypes.c_void_p, ctypes.c_int8] + + res = fun(field, layer) + if res == 1: + raise Exception() \ No newline at end of file diff --git a/src/interfaces/reader/eas3.c b/src/interfaces/reader/eas3.c old mode 100644 new mode 100755 index 5a6a6cf..e9184e8 --- a/src/interfaces/reader/eas3.c +++ b/src/interfaces/reader/eas3.c @@ -1,123 +1,85 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ - -/************************************************************************************************************\ -|| _ _ _ ____ _ _ _ ___ ____ || -|| | |\ | | | | | | \ |___ || -|| | | \| |___ |___ |__| |__/ |___ || -|| || -\************************************************************************************************************/ +/*====================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This file defines simple read and write functions used to access conforming eas3 || +|| datasets. || +|| || +|| ---------------------------------------------------------------------------------------------------------------- || +|| || +|| 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. || +|| || +\*====================================================================================================================*/ +/**********************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\**********************************************************************************************************************/ #include -#include +#include #include #include #include +#include "bitstream.h" #include "eas3.h" -#include "bwccmdl.h" +#include "field.h" +#include "macros.h" +#include "types.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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/**********************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function converts the endianess of single or double precision values. ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! value - Memory address of the parameter to be converted. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -endian_conversion(void *value, - uint8_t const accuracy) +endian_conversion(void *value, + uint8 const accuracy) { /*-----------------------*\ ! DEFINE ASSERTIONS: ! @@ -126,39 +88,29 @@ endian_conversion(void *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; + uint32 *tmp = (uint32*)value; - *tmp = (uint32_t)((*tmp << 8) & 0xFF00FF00) | - (uint32_t)((*tmp >> 8) & 0x00FF00FF); + *tmp = (uint32)((*tmp << 8) & 0xFF00FF00) | + (uint32)((*tmp >> 8) & 0x00FF00FF); - *tmp = (uint32_t)( *tmp << 16) | - (uint32_t)( *tmp >> 16); + *tmp = (uint32)( *tmp << 16) | + (uint32)( *tmp >> 16); break; } - case 8: { - uint64_t *tmp = (uint64_t*)value; + uint64 *tmp = (uint64*)value; - *tmp = (uint64_t)((*tmp << 8) & 0xFF00FF00FF00FF00ULL) | - (uint64_t)((*tmp >> 8) & 0x00FF00FF00FF00FFULL); + *tmp = (uint64)((*tmp << 8) & 0xFF00FF00FF00FF00ULL) | + (uint64)((*tmp >> 8) & 0x00FF00FF00FF00FFULL); - *tmp = (uint64_t)((*tmp << 16) & 0xFFFF0000FFFF0000ULL) | - (uint64_t)((*tmp >> 16) & 0x0000FFFF0000FFFFULL); + *tmp = (uint64)((*tmp << 16) & 0xFFFF0000FFFF0000ULL) | + (uint64)((*tmp >> 16) & 0x0000FFFF0000FFFFULL); - *tmp = (uint64_t)( *tmp << 32) | - (uint64_t)( *tmp >> 32); + *tmp = (uint64)( *tmp << 32) | + (uint64)( *tmp >> 32); break; } default: @@ -168,960 +120,2084 @@ endian_conversion(void *value, } } -/*----------------------------------------------------------------------------------------------------------*\ -! 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) +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to properly deallocate a eas3 numerical dataset in the field ! +! structure. All pointers and paramters are properly reinitialize to NULL/0. ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! field - Structure defining and controlling a (de-) ! +! compression run. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static void +free_eas3(bwc_field *field) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 Lread; - uint64 i; - uint8 precision; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 t; - /*-----------------------*\ - ! DEFINE CHAR VARIABLES: ! - \*-----------------------*/ - uchar *buffer_char; - char param_name[ATTRLEN + 1] = {}; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + eas3_file_util *tmp; + bwc_cmd_opts_ll *param, *temp; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_gl_inf *info; - bwc_stream *aux; - eas3_std_params params; + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); - /*-----------------------*\ - ! DEFINE FILE POINTER: ! - \*-----------------------*/ - FILE *fp; + /*--------------------------------------------------------*\ + ! If the numerical dataset was set to read, deallocate the ! + ! parameter linked list and reset the global info and con- ! + ! trol structure. ! + \*--------------------------------------------------------*/ + if((field->codestream.flag & DATA_IN) != 0) + { + if(field->info.parameter != NULL) + { + param = field->info.parameter->root; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(data); + while(param != NULL) + { + temp = param; + param = param -> next; + free(temp); + } + } - /*--------------------------------------------------------*\ - ! 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; + free(field->control.packed_tile_size); - /*--------------------------------------------------------*\ - ! Allocate the character buffer used to store chunks of ! - ! memory read from the specified file. ! - \*--------------------------------------------------------*/ - buffer_char = calloc(20, sizeof(uchar)); - if(!buffer_char) - { + memset(&field->control, 0, sizeof(bwc_gl_ctrl)); + memset(&field->info, 0, sizeof(bwc_gl_inf)); + } + + /*--------------------------------------------------------*\ + ! If allocated, release the tile parameters as well as the ! + ! pointer array used to store their memory addresses. ! + \*--------------------------------------------------------*/ + if((field->data.limit > 0) && + (field->data.body != NULL)) + { + for(t = 0; t < field->data.limit; ++t) + { + if(field->data.body[t].size > 0) + { + field->memory.usage.data -= field->data.body[t].size; + free(field->data.body[t].memory); + } + } + + free(field->data.body); + + field->data.body = NULL; + field->data.limit = 0; + field->data.count = 0; + field->data.idx = 0; + } + + /*--------------------------------------------------------*\ + ! Dereference the memory address to the eas3 utility struc-! + ! ture and properly deallocate it. ! + \*--------------------------------------------------------*/ + if(field->data.util != NULL) + { + tmp = (eas3_file_util*)field->data.util; + + free(tmp->offset); + free(field->data.util); + + field->data.util = NULL; + } + + /*--------------------------------------------------------*\ + ! Close the file pointer and reinitialize the remaining ! + ! pointers and paramters. ! + \*--------------------------------------------------------*/ + fclose(field->data.fp); + field->data.flag = DATA_CLR; + field->data.fp = NULL; + field->data.IO = NULL; + field->data.free = NULL; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to read the header from a conforming eas3 file and store its ! +! information in the bwc_field structure. In case of an error the function will free ! +! all allocated memory, including the auxiliary information block, and return an error ! +! handle to the function caller. ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! field - Structure defining and controlling a (de-) ! +! compression run. ! +! ! +! RETURN: ! +! ------- ! +! Returns an unsigned char for error handling. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static uchar +read_eas3_header(bwc_field *const field) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 Lread; + uint64 i; + uint8 precision; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar *buffer, *tmp; + 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(field); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + info = &field->info; + fp = field->data.fp; + + /*--------------------------------------------------------*\ + ! Allocate the character buffer, read the first 20 bits of ! + ! the specified file and check if the file identifier cor- ! + ! responds to a valid EAS file. ! + \*--------------------------------------------------------*/ + buffer = calloc(20, sizeof(uchar)); + if(buffer == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return 1; - } + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! 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) - { + if(fread(buffer, sizeof(uchar) , 20, fp) != 20) + { // invalid read fprintf(stderr, RDERROR); - free(buffer_char); - return 1; - } + free(buffer); + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! 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")) - { + if(strstr((char*)buffer, "EAS3_I8R8") == NULL) + { // 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) - { + free(buffer); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Initialize the auxiliary information stream. The initial ! + ! size has been chosen arbitrarily and should be large e- ! + ! nough to prevent excessive reallocation. ! + \*--------------------------------------------------------*/ + aux = init_stream(NULL, AUX_SIZE, 'c'); + if(aux == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - free(buffer_char); - return 1; - } + free(buffer); + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! 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) - { + /*--------------------------------------------------------*\ + ! Read the standard eas parameters from the file and check ! + ! if the specified file is of the EAS3 type. If true, emit ! + ! them to the auxiliary information stream. ! + \*--------------------------------------------------------*/ + if(fread(¶ms, sizeof(uint64), 22, fp) != 22) + { // invalid read fprintf(stderr, RDERROR); - free(buffer_char); - return 1; - } + terminate_stream(aux, NULL); + free(buffer); + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! Check if the specified file is of the EAS3 type. ! - \*--------------------------------------------------------*/ - if(params.file_type == EAS2_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; - } + terminate_stream(aux, NULL); + free(buffer); + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! 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); + emit_chunck(aux, (uchar*)¶ms, 176); - /*--------------------------------------------------------*\ - ! 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) - { + /*--------------------------------------------------------*\ + ! Convert all parameters required for eas3 file operations ! + ! to little endian. All parameters necessary to instruct ! + ! the bwc codec are stored in the bwc_field structure. ! + \*--------------------------------------------------------*/ + endian_conversion(¶ms.ndim1, 8); + endian_conversion(¶ms.ndim2, 8); + endian_conversion(¶ms.ndim3, 8); + endian_conversion(¶ms.nzs, 8); + endian_conversion(¶ms.npar, 8); + 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); + + info->nX = (uint64)params.ndim1; + info->nY = (uint64)params.ndim2; + info->nZ = (uint64)params.ndim3; + info->nTS = (uint16)params.nzs; + info->numParams = (uint8)params.npar; + + if(params.accuracy == 1) + { + precision = 4; + } + else if(params.accuracy == 2) + { + precision = 8; + } + else + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Invalid bit precision |\n"\ + "| |\n"\ + "| The bit precision of the specified dataset |\n"\ + "| is not supported by the compression algo- |\n"\ + "| rithm. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Adjust the buffer size and read the time step array from ! + ! the eas3 file. If successful, emit the data to the aux- ! + ! iliary information memory block. ! + \*--------------------------------------------------------*/ + tmp = realloc(buffer, info->nTS * sizeof(uint64)); + if(tmp == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return 1; - } - - if(fread(buffer_char, sizeof(uint64), info->nTS, fp) != info->nTS) - { + terminate_stream(aux, NULL); + free(buffer); + return EXIT_FAILURE; + } + else + { + buffer = tmp; + } + + if(fread(buffer, sizeof(uint64), info->nTS, fp) != info->nTS) + { // invalid read fprintf(stderr, RDERROR); - free(buffer_char); - return 1; - } + terminate_stream(aux, NULL); + free(buffer); + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! Emit the time step array to the auxiliary information ! - ! memory block. ! - \*--------------------------------------------------------*/ - bwc_emit_chunck(aux, buffer_char, info->nTS * sizeof(uint64)); + emit_chunck(aux, buffer, info->nTS * sizeof(uint64)); - /*--------------------------------------------------------*\ - ! Check if any attributes have been specified in the eas3 ! - ! file. ! - \*--------------------------------------------------------*/ - if(params.attribute_mode == EAS3_ALL_ATTR) - { + /*--------------------------------------------------------*\ + ! 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. ! + ! Adjust the buffer size and read the time step attributes ! + ! from the eas3 file. If successful, emit the data to the ! + ! auxiliary information memory block. ! \*--------------------------------------------------------*/ - buffer_char = realloc(buffer_char, info->nTS * ATTRLEN * sizeof(char)); - if(!buffer_char) - { - // memory allocation error - fprintf(stderr, MEMERROR); - free(buffer_char); - return 1; - } + tmp = realloc(buffer, info->nTS * ATTRLEN * sizeof(char)); + if(tmp == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + terminate_stream(aux, NULL); + free(buffer); + return EXIT_FAILURE; + } + else + { + buffer = tmp; + } + + if(fread(buffer, sizeof(char), info->nTS * ATTRLEN, fp) != (info->nTS * ATTRLEN)) + { + // invalid read + fprintf(stderr, RDERROR); + terminate_stream(aux, NULL); + free(buffer); + return EXIT_FAILURE; + } - if(fread(buffer_char, sizeof(char), info->nTS * ATTRLEN, fp) != (info->nTS * ATTRLEN)) - { - // invalid read - fprintf(stderr, RDERROR); - free(buffer_char); - return 1; - } + emit_chunck(aux, buffer, info->nTS * ATTRLEN * sizeof(char)); /*--------------------------------------------------------*\ - ! Emit the timestep attribute array to the auxiliary infor-! - ! mation memory block. ! + ! Loop through the available parameters and ... ! \*--------------------------------------------------------*/ - bwc_emit_chunck(aux, buffer_char, info->nTS * ATTRLEN * sizeof(char)); + for(i = 0; i < info->numParams; ++i) + { + /*--------------------------------------------------------*\ + ! read the parameter name from the file stream, add all ! + ! the necessary parameter information to the paramter ! + ! linked list and reset the parameter name char. array. ! + \*--------------------------------------------------------*/ + if(fread(param_name, sizeof(char), ATTRLEN, fp) != ATTRLEN) + { + // invalid read + fprintf(stderr, RDERROR); + terminate_stream(aux, NULL); + free(buffer); + return EXIT_FAILURE; + } - 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(field, param_name, 0, (DIM_X | DIM_Y | DIM_Z), precision); - bwc_add_param(data, param_name, 0, (DIM_X | DIM_Y | DIM_Z), precision); + memset(param_name, 0, ATTRLEN + 1); + } + } - /*--------------------------------------------------------*\ - ! 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; - /*--------------------------------------------------------*\ - ! 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) - { + /*--------------------------------------------------------*\ + ! Adjust the buffer size and read the remaining bytes from ! + ! the file header. If successful, emit the information to ! + ! the auxiliary information memory block. ! + \*--------------------------------------------------------*/ + tmp = realloc(buffer, Lread * sizeof(uchar)); + if(tmp == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - free(buffer_char); - return 1; - } + terminate_stream(aux, NULL); + free(buffer); + return EXIT_FAILURE; + } + else + { + buffer = tmp; + } - /*--------------------------------------------------------*\ - ! Read the remaining header bytes from the file stream. ! - \*--------------------------------------------------------*/ - if(fread(buffer_char, sizeof(uchar), Lread, fp) != Lread) - { + if(fread(buffer, sizeof(uchar), Lread, fp) != Lread) + { // invalid read fprintf(stderr, RDERROR); - free(buffer_char); - return 1; - } + terminate_stream(aux, NULL); + free(buffer); + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! 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); + emit_chunck(aux, buffer, Lread); - /*--------------------------------------------------------*\ - ! 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; - } + /*--------------------------------------------------------*\ + ! Terminate and save the auxiliary information stream in ! + ! the bwc_field structure. If successful, free the buffer ! + ! and return to the function caller. ! + \*--------------------------------------------------------*/ + if(terminate_stream(aux, &field->codestream.header.aux) == EXIT_FAILURE) + { + free(buffer); + return EXIT_FAILURE; + } + field->memory.usage.data += field->codestream.header.aux.size; - return 0; + free(buffer); + + return EXIT_SUCCESS; } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to write the header for a conforming eas3 file from the ! +! information stored in the bwc_field structure. In case of an error the function will ! +! free all allocated memory and return an error handle to the function caller. ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! field - Structure defining and controlling a (de-) ! +! compression run. ! +! ! +! RETURN: ! +! ------- ! +! Returns an unsigned char for error handling. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static uchar -write_eas3_header(bwc_data *const data) +write_eas3_header(bwc_field *const field) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 Lwrite; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 Lwrite; - /*-----------------------*\ - ! DEFINE CHAR VARIABLES: ! - \*-----------------------*/ - uchar *buffer_char; + /*-----------------------*\ + ! 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 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); + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp; - /*--------------------------------------------------------*\ - ! 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; + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); - /*--------------------------------------------------------*\ - ! Write the valid EAS3 identifier to the specified file. ! - \*--------------------------------------------------------*/ - if(fwrite("EAS3_I8R8 ", sizeof(char), 20, fp) != 20) - { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + info = &field->info; + fp = field->data.fp; + + /*--------------------------------------------------------*\ + ! Write the file identifier for a vonforming EAS3 file to ! + ! the specified file pointer. ! + \*--------------------------------------------------------*/ + if(fwrite("EAS3_I8R8 ", sizeof(char), 20, fp) != 20) + { // invalid read fprintf(stderr, WRTERROR); - return 1; - } + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! Initialize the auxiliary information stream. ! - \*--------------------------------------------------------*/ - aux = bwc_init_stream(data->codestream.aux->memory, - data->codestream.aux->size, 'd'); + /*--------------------------------------------------------*\ + ! Initialize the auxiliary information stream. ! + \*--------------------------------------------------------*/ + aux = init_stream(field->codestream.header.aux.memory, + field->codestream.header.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); + /*--------------------------------------------------------*\ + ! Extract the standard paramters from the auxiliary infor- ! + ! mation stream and write them to the eas3 file. ! + \*--------------------------------------------------------*/ + params = (eas3_std_params*)get_chunck(aux, 176); - if(fwrite(params, sizeof(uint64), 22, fp) != 22) - { + if(fwrite(params, sizeof(uint64), 22, fp) != 22) + { // invalid read fprintf(stderr, WRTERROR); - return 1; - } + free(aux); + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! 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); + /*--------------------------------------------------------*\ + ! Convert all parameters required for eas3 file operations ! + ! 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) - { + /*--------------------------------------------------------*\ + ! Extract the time step array from the auxiliary informa- ! + ! tion stream, write it to the file stream and deallocate ! + ! the buffer character array. ! + \*--------------------------------------------------------*/ + buffer_char = get_chunck(aux, info->nTS * sizeof(uint64)); + if(buffer_char == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - free(buffer_char); - return 1; - } + free(params); + free(aux); + return EXIT_FAILURE; + } - if(fwrite(buffer_char, sizeof(uint64), info->nTS, fp) != info->nTS) - { + if(fwrite(buffer_char, sizeof(uint64), info->nTS, fp) != info->nTS) + { // invalid read fprintf(stderr, WRTERROR); free(buffer_char); - return 1; - } - free(buffer_char); + free(params); + free(aux); + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! Check if any attributes have been specified in the aux- ! - ! iliary information block. ! - \*--------------------------------------------------------*/ - if(params->attribute_mode == EAS3_ALL_ATTR) - { + 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. ! + ! Extract the time step attribute array from the auxiliary ! + ! information stream, write it to the file stream and de- ! + ! allocate the buffer character array. ! \*--------------------------------------------------------*/ - buffer_char = bwc_get_chunck(aux, info->nTS * ATTRLEN); - if(!buffer_char) - { - // memory allocation error - fprintf(stderr, MEMERROR); - free(buffer_char); - return 1; - } + buffer_char = get_chunck(aux, info->nTS * ATTRLEN); + if(buffer_char == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(params); + free(aux); + return EXIT_FAILURE; + } if(fwrite(buffer_char, sizeof(uchar), info->nTS * ATTRLEN, fp) != (info->nTS * ATTRLEN)) - { - // invalid read - fprintf(stderr, WRTERROR); - free(buffer_char); - return 1; - } + { + // invalid read + fprintf(stderr, WRTERROR); + free(buffer_char); + free(params); + free(aux); + return EXIT_FAILURE; + } + free(buffer_char); /*--------------------------------------------------------*\ ! Loop through the parameter array and... ! \*--------------------------------------------------------*/ - if(data->info.parameter) - { - param = data->info.parameter->root; + if(field->info.parameter) + { + param = field->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) + while(param != NULL) { - // invalid read - fprintf(stderr, WRTERROR); - free(buffer_char); - return 1; + /*--------------------------------------------------------*\ + ! ... 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(params); + free(aux); + return EXIT_FAILURE; + } + + param = param -> next; } + } + } - 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; - /*--------------------------------------------------------*\ - ! 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) - { + /*--------------------------------------------------------*\ + ! Extract the remaining bytes from the auxiliary informa- ! + ! tion stream, write them to the file stream and deallo- ! + ! cate the buffer character array. ! + \*--------------------------------------------------------*/ + buffer_char = get_chunck(aux, Lwrite); + if(buffer_char == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - free(buffer_char); - return 1; - } + free(params); + free(aux); + return EXIT_FAILURE; + } - if(fwrite(buffer_char, sizeof(uchar), Lwrite, fp) != Lwrite) - { + if(fwrite(buffer_char, sizeof(uchar), Lwrite, fp) != Lwrite) + { // invalid read fprintf(stderr, WRTERROR); free(buffer_char); - return 1; - } - free(buffer_char); + free(params); + free(aux); + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! Free the auxiliary information memory block stream and ! - ! params structure. ! - \*--------------------------------------------------------*/ - free(aux); - free(params); + free(buffer_char); - return 0; + /*--------------------------------------------------------*\ + ! Free the auxiliary information stream and params struc- ! + ! ture and return to the function caller. ! + \*--------------------------------------------------------*/ + free(params); + free(aux); + + return EXIT_SUCCESS; } -/************************************************************************************************************\ -|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || -|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || -|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || -|| || -\************************************************************************************************************/ -/*----------------------------------------------------------------------------------------------------------*\ -! 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) +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! | | ! +! This function is used to read a tile from a specific parameter stored in an eas3 ! +! file. If the tileID equals the number of user specified tiles, the entire parameter ! +! is read from the file. ! +! In case of an error, the function will free the temporary buffer and return an error ! +! flag to the function caller. ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! stream - ! +! ! +! RETURN: ! +! ------- ! +! Number of bites that have been written to the bitstream. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining and control- ! +! ling a (de-)compression run. ! +! ! +! dataID unsigned int(64 bit) - Packed data stream Index. ! +! ! +! tileID unsigned int(64 bit) - Tile Index. ! +! ! +! parID unsigned int(8 bit) - Parameter Index. ! +! ! +! 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. ! +! 12.03.2020 Patrick Vogler B87E7E4 V 0.1.0 refactored read fuction ! +! to define a unified in- ! +! terface for additional ! +! file formats. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static uchar +read_eas3(bwc_field *const field, + uint64 const dataID, + uint64 const tileID, + uint8 const parID) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 Lfield; - uint64 i; - uint32 root; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 width, height; + uint64 depth, dt; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_data *data; + uint64 buffer_width; - /*--------------------------------------------------------*\ - ! Allocate the data structure. ! - \*--------------------------------------------------------*/ - data = calloc(1, sizeof(bwc_data)); - if(!data) - { + uint64 sampX, sampY; + uint64 sampZ, sampTS; + + uint64 parSize; + uint64 parOffset; + + uint64 X0, Y0, Z0, TS0; + uint64 X1, Y1, Z1, TS1; + + uint64 w, x, y, z, t; + + uint8 parPrec; + + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + bwc_float *data; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar *buffer; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_inf *info; + bwc_tile_inf *tile_info; + + bwc_cmd_opts_ll *param; + + eas3_file_util *util; + + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(dataID < field->data.limit); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + info = &field->info; + util = field->data.util; + fp = field->data.fp; + + /*--------------------------------------------------------*\ + ! Extract the tile info and linked list node for the cur- ! + ! rent tile- and parID. ! + \*--------------------------------------------------------*/ + tile_info = &field->setup.canvas[tileID]; + + for(param = info->parameter->root; param->id != parID; param = param->next) + { + if(param == NULL) + { + // invalid paramter ID + fprintf(stderr, PARERROR); + return EXIT_FAILURE; + } + } + + /*--------------------------------------------------------*\ + ! Safe the tile parameter offset and precision in temporar-! + ! y variables and evaluate the sample rates as well as its ! + ! width, height, depth and dt ! + \*--------------------------------------------------------*/ + parOffset = util->offset[parID]; + parPrec = param->precision; + parSize = 0; + + sampX = (param->dim & 1) ? (1 << param->sample) : 1; + sampY = (param->dim & 2) ? (1 << param->sample) : 1; + sampZ = (param->dim & 4) ? (1 << param->sample) : 1; + sampTS = (param->dim & 8) ? (1 << param->sample) : 1; + + X0 = tile_info->X0; + X1 = tile_info->X1; + width = (uint64)ceil((float)X1 / sampX) - + (uint64)ceil((float)X0 / sampX); + + Y0 = tile_info->Y0; + Y1 = tile_info->Y1; + height = (uint64)ceil((float)Y1 / sampY) - + (uint64)ceil((float)Y0 / sampY); + + Z0 = tile_info->Z0; + Z1 = tile_info->Z1; + depth = (uint64)ceil((float)Z1 / sampZ) - + (uint64)ceil((float)Z0 / sampZ); + + TS0 = tile_info->TS0; + TS1 = tile_info->TS1; + dt = (uint64)ceil((float)TS1 / sampTS) - + (uint64)ceil((float)TS0 / sampTS); + + /*--------------------------------------------------------*\ + ! Allocate the data memory block and read buffer used to ! + ! cache a widths worth of IEEE 754 values in memory. ! + \*--------------------------------------------------------*/ + data = calloc(width * height * depth * dt, sizeof(bwc_float)); + if(data == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return NULL; - } + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! Set the file identifier used to select the appropriate ! - ! write operation during decompression. ! - \*--------------------------------------------------------*/ - strncpy(data->info.f_ext, "eas", 4); + buffer_width = X1 - X0; + buffer = calloc(buffer_width * parPrec, sizeof(uchar)); + if(buffer == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(data); + return EXIT_FAILURE; + } + /*--------------------------------------------------------*\ + ! Iterate over all tile parameter columns and load them ! + ! into memory. ! + \*--------------------------------------------------------*/ + if(parPrec == 4) + { + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + bwc_float *dest; + float *src; - /*--------------------------------------------------------*\ - ! 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; - } + for(t = 0; t < dt; ++t) + { + for(z = 0; z < depth; ++z) + { + for(y = 0; y < height; ++y) + { + /*--------------------------------------------------------*\ + ! Advance the file and data pointers to the next column, ! + ! load the samples into the read buffer and rewind the ! + ! source pointer to the first sample in the column. ! + \*--------------------------------------------------------*/ + fseek(fp, parOffset + parPrec * (X0 + info->nX * + (Y0 + y * sampY + info->nY * + (Z0 + z * sampZ + info->nZ * t * sampTS))), SEEK_SET); - /*--------------------------------------------------------*\ - ! 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); - } + dest = &data[(uint64)width * (y + height * (z + depth * t))]; - /*--------------------------------------------------------*\ - ! 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); + if(fread(&buffer, buffer_width, parPrec, fp) != buffer_width) + { + // invalid read + fprintf(stderr, RDERROR); + free(buffer); + free(data); + return EXIT_FAILURE; + } + else + { + parSize += buffer_width; + } - /*--------------------------------------------------------*\ - ! 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; - } + src = (float*)buffer; - 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; - } + /*--------------------------------------------------------*\ + ! Loup over the column, convert the data samples to little ! + ! endian and store them in the data block. ! + \*--------------------------------------------------------*/ + for(w = 0, x = 0; w < width; ++w, x += sampX) + { + endian_conversion(&src[x], parPrec); - /*--------------------------------------------------------*\ - ! 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; - } + dest[w] = (bwc_float)src[x]; + } + } + } + } + } + else if(parPrec == 8) + { + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + bwc_float *dest; + double *src; - /*--------------------------------------------------------*\ - ! 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; - } + for(t = 0; t < dt; ++t) + { + for(z = 0; z < depth; ++z) + { + for(y = 0; y < height; ++y) + { + /*--------------------------------------------------------*\ + ! Advance the file and data pointers to the next column, ! + ! load the samples into the read buffer and rewind the ! + ! source pointer to the first sample in the column. ! + \*--------------------------------------------------------*/ + fseek(fp, parOffset + parPrec * (X0 + info->nX * + (Y0 + y * sampY + info->nY * + (Z0 + z * sampZ + info->nZ * t * sampTS))), SEEK_SET); - /*--------------------------------------------------------*\ - ! 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; - } + dest = &data[(uint64)width * (y + height * (z + depth * t))]; + + if(fread(buffer, parPrec, buffer_width, fp) != buffer_width ) + { + // invalid read + fprintf(stderr, RDERROR); + free(buffer); + free(data); + return EXIT_FAILURE; + } + else + { + parSize += buffer_width; + } - /*--------------------------------------------------------*\ - ! 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); - } - } + src = (double*)buffer; - /*--------------------------------------------------------*\ - ! Close the file pointer and return the bwc_data structure ! - ! to the function caller. ! - \*--------------------------------------------------------*/ - fclose(data->file.fp); - data->file.fp = NULL; - return data; + /*--------------------------------------------------------*\ + ! Loup over the column, convert the data samples to little ! + ! endian and store them in the data block. ! + \*--------------------------------------------------------*/ + for(w = 0, x = 0; w < width; ++w, x += sampX) + { + endian_conversion(&src[x], parPrec); + + dest[w] = (bwc_float)src[x]; + } + } + } + } + } + else + { + // invalid precision + fprintf(stderr, PRCERROR); + free(buffer); + free(data); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Properly set up the packed data stream corresponding to ! + ! the user supplied ID and adjust the memory usage. ! + \*--------------------------------------------------------*/ + field->data.body[dataID].param = parID; + field->data.body[dataID].tile = tileID; + + field->data.body[dataID].access = + field->data.body[dataID].memory = (uchar*)data; + + field->data.body[dataID].size = (parSize * parPrec); + + field->data.count++; + + field->memory.usage.data += (parSize * parPrec); + + /*--------------------------------------------------------*\ + ! Free the temporary buffer and return to the function ! + ! caller. ! + \*--------------------------------------------------------*/ + free(buffer); + + return EXIT_SUCCESS; } -/*----------------------------------------------------------------------------------------------------------*\ -! 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) +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! | | ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! stream - ! +! ! +! RETURN: ! +! ------- ! +! Number of bites that have been written to the bitstream. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to write a tile from a specific parameter stored in a ! +! bwc file to an eas3 file. In case of an error, the function will free the tem- ! +! porary buffer and return an error flag to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining and control- ! +! ling a (de-)compression run. ! +! ! +! dataID unsigned int(64 bit) - Packed data stream Index. ! +! ! +! tileID unsigned int(64 bit) - Tile Index. ! +! ! +! parID unsigned int(8 bit) - Parameter Index. ! +! ! +! 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. ! +! 12.03.2020 Patrick Vogler B87E7E4 V 0.1.0 refactored write func- ! +! tion to define a uni- ! +! fied interface for addi- ! +! tional file formats. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static uchar +write_eas3(bwc_field *const field, + uint64 const dataID, + uint64 const tileID, + uint8 const parID) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 Lfield; - uint64 i; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(data); + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 width, height; + uint64 depth, dt; - /*--------------------------------------------------------*\ - ! 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 + uint64 sampX, sampY; + uint64 sampZ, sampTS; + + uint64 parOffset; + + uint64 X0, Y0, Z0, TS0; + uint64 X1, Y1, Z1, TS1; + + uint64 nX, nY, nZ; + + uint64 x, y, z, t; + + uint32 root; + + uint16 p; + + uint8 parPrec; + + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + bwc_float *data; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar *buffer; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_inf *info; + bwc_tile_inf *tile_info; + + bwc_cmd_opts_ll *param; + + eas3_file_util *util; + + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(dataID < field->data.limit); + + /*--------------------------------------------------------*\ + ! Save the global info and file utility structure as well ! + ! as the file pointer in temporary variables to make the ! + ! code more readable. ! + \*--------------------------------------------------------*/ + info = &field->info; + util = field->data.util; + fp = field->data.fp; + + /*--------------------------------------------------------*\ + ! If it hasn't happened already, properly initialize the ! + ! data file and data utility structure. ! + \*--------------------------------------------------------*/ + if((field->data.flag & DATA_INI) == 0) + { + /*--------------------------------------------------------*\ + ! If the user supplied codestream supports the file format ! + ! write the header information to file. ! + \*--------------------------------------------------------*/ + if(strcmp("eas3", field->info.file_ext)) + { + //File error + fprintf(stderr, FRMERROR); + return EXIT_FAILURE; + } + + if(write_eas3_header(field) == EXIT_FAILURE) + { + // invalid read + fprintf(stderr, WRTERROR); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Evaluate the parameter root and allocate and initialize ! + ! the parameter offset structure. ! + \*--------------------------------------------------------*/ + root = ftell(fp); + + util->offset = calloc(field->info.numParams, sizeof(uint64)); + if(util->offset == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + + for(p = 0; p < field->info.numParams; ++p) + { + for(param = info->parameter->root; param->id != p; param = param->next); + + if(p == 0) + { + util->offset[p] = root + (param->size * param->precision); + } + else + { + util->offset[p] = util->offset[p - 1] + (param->size * param->precision); + } + } + /*--------------------------------------------------------*\ + ! Modify the data flag to indicate that it has been init. ! + \*--------------------------------------------------------*/ + field->data.flag |= DATA_INI; + } + + /*--------------------------------------------------------*\ + ! Extract the tile info and linked list node for the cur- ! + ! rent tile- and parID. ! + \*--------------------------------------------------------*/ + tile_info = &field->setup.canvas[tileID]; + + for(param = info->parameter->root; param->id != parID; param = param->next) + { + if(param == NULL) + { + // invalid paramter ID + fprintf(stderr, PARERROR); + return EXIT_FAILURE; + } + } + + /*--------------------------------------------------------*\ + ! Safe the offset for the current tile parameter in a tem- ! + ! porary variable and evaluate its width, height, depth ! + ! and dt as well as the corresponding sample rates. ! + \*--------------------------------------------------------*/ + parOffset = util->offset[parID]; + parPrec = param->precision; + + sampX = (param->dim & 1) ? (1<sample) : 1; + sampY = (param->dim & 2) ? (1<sample) : 1; + sampZ = (param->dim & 4) ? (1<sample) : 1; + sampTS = (param->dim & 8) ? (1<sample) : 1; + + nX = (uint64)ceil((float)info->nX / sampX); + X0 = (uint64)ceil((float)tile_info->X0 / sampX); + X1 = (uint64)ceil((float)tile_info->X1 / sampX); + width = X1 - X0; + + nY = (uint64)ceil((float)info->nY / sampY); + Y0 = (uint64)ceil((float)tile_info->Y0 / sampY); + Y1 = (uint64)ceil((float)tile_info->Y1 / sampY); + height = Y1 - Y0; + + nZ = (uint64)ceil((float)info->nZ / sampZ); + Z0 = (uint64)ceil((float)tile_info->Z0 / sampZ); + Z1 = (uint64)ceil((float)tile_info->Z1 / sampZ); + depth = Z1 - Z0; + + TS0 = (uint16)ceil((float)tile_info->TS0 / sampTS); + TS1 = (uint16)ceil((float)tile_info->TS1 / sampTS); + dt = TS1 - TS0; + + /*--------------------------------------------------------*\ + ! Retrieve the tile parameter data block and allocate the ! + ! temporary buffer used to cache a widths worth of IEEE ! + ! 754 values in memory. ! + \*--------------------------------------------------------*/ + data = (bwc_float*)field->data.body[dataID].memory; + if(data == NULL) + { + // invalid paramter ID + fprintf(stderr, PARERROR); + return EXIT_FAILURE; + } + + buffer = calloc(width * parPrec, sizeof(char)); + if(buffer == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Iterate over all tile parameter columns and load them ! + ! into memory. ! + \*--------------------------------------------------------*/ + if(parPrec == 4) + { + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + bwc_float *src; + float *dest; + + for(t = 0; t < dt; ++t) + { + for(z = 0; z < depth; ++z) + { + for(y = 0; y < height; ++y) + { + /*--------------------------------------------------------*\ + ! Advance the file and working buffer pointer to the next ! + ! column and rewind the temporary buffer pointer to the ! + ! first sample. ! + \*--------------------------------------------------------*/ + fseek(fp, parOffset + parPrec * (X0 + nX * + (Y0 + y + nY * + (Z0 + z + nZ * t))), SEEK_SET); + + + src = &data[(uint64)width * (y + height * (z + depth * t))]; + dest = (float*)buffer; + + /*--------------------------------------------------------*\ + ! Loup over the column, copy the data samples to the writ- ! + ! ing buffer and convert them to big endian. ! + \*--------------------------------------------------------*/ + for(x = 0; x < width; ++x) + { + dest[x] = (float)src[x]; + + endian_conversion(&dest[x], parPrec); + } + + /*--------------------------------------------------------*\ + ! Write the transformed samples to the eas3 file. ! + \*--------------------------------------------------------*/ + if(fwrite(&buffer, width, parPrec, fp) != width) + { + // invalid read + fprintf(stderr, WRTERROR); + free(buffer); + return EXIT_FAILURE; + } + } + } + } + } + else if(parPrec == 8) + { + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + bwc_float *src; + double *dest; + + for(t = 0; t < dt; ++t) + { + for(z = 0; z < depth; ++z) + { + for(y = 0; y < height; ++y) + { + /*--------------------------------------------------------*\ + ! Advance the file and working buffer pointer to the next ! + ! column and rewind the temporary buffer pointer to the ! + ! first sample. ! + \*--------------------------------------------------------*/ + fseek(fp, parOffset + sizeof(double) * (X0 + nX * + (Y0 + y + nY * + (Z0 + z + nZ * t))), SEEK_SET); + + src = &data[(uint64)width * (y + height * (z + depth * t))]; + dest = (double*)buffer; + + /*--------------------------------------------------------*\ + ! Loup over the column, copy the data samples to the writ- ! + ! ing buffer and convert them to big endian. ! + \*--------------------------------------------------------*/ + for(x = 0; x < width; ++x) + { + dest[x] = (double)src[x]; + + endian_conversion(&dest[x], parPrec); + } + + /*--------------------------------------------------------*\ + ! Write the transformed samples to the eas3 file. ! + \*--------------------------------------------------------*/ + if(fread(&buffer, width, parPrec, fp) != width) + { + // invalid read + fprintf(stderr, WRTERROR); + free(buffer); + return EXIT_FAILURE; + } + } + } + } + } + else + { + // invalid precision + fprintf(stderr, PRCERROR); + free(buffer); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Free the temporary buffer and return to the function ! + ! caller. ! + \*--------------------------------------------------------*/ + free(buffer); + + return EXIT_SUCCESS; +} + +/**********************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! | | ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! stream - ! +! ! +! RETURN: ! +! ------- ! +! Number of bites that have been written to the bitstream. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function initializes an eas3 numerical dataset in the bwc_field structure ! +! with the corresponding utility structure as well as the suitable free function. ! +! If the file operation mode is set to read 'r', the function opens the speci- ! +! fied file, parses its header and checks its validity. If verified, the header ! +! information, alongside the file pointer and appropriate read function, is ! +! stored in the bwc_field structure. ! +! If the file operation mode is set to read 'w', the function opens and writes ! +! the header information to the specified file. If successful, the file pointer ! +! and appropriate write function are stored in the bwc_field structure. ! +! In case of an error, the function will properly free the numerical dataset in ! +! the bwc_field structure and return an error flag to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining and control- ! +! ling a (de-)compression run. ! +! ! +! filename char* - Name of an eas3 file. ! +! ! +! mode char* - File operations mode - 'r' for ! +! read / 'w' for write. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 09.03.2020 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +uchar +open_eas3(bwc_field *const field, + char const *const filename, + char const *const mode) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 Lfield, Lfile; + uint32 root; + uint16 p; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_inf *info; + + eas3_file_util *util; + bwc_cmd_opts_ll *param; + + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(filename); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + info = &field->info; + + /*--------------------------------------------------------*\ + ! Verify that the numerical field has not been set and i- ! + ! nitialize it with the proper utility structure and free ! + ! function. ! + \*--------------------------------------------------------*/ + if(field->data.flag != DATA_CLR) + { + // invalid read operation fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: Could not open or write %-24s|\n"\ - "o##########################################################o\n", filename); - return 1; - } + "| ERROR: Invalid IO |\n"\ + "| |\n"\ + "| The supplied bwc_field structure is already |\n"\ + "| set to read from or write to a numerical |\n"\ + "| data-set. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! Write the eas3 header to the specified file. ! - \*--------------------------------------------------------*/ - if(write_eas3_header(data)) - { - //error reading eas3 header - return 1; - } + util = calloc(1, sizeof(eas3_file_util)); + if(util == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free_eas3(field); + return EXIT_FAILURE; + } + field->memory.usage.data += sizeof(eas3_file_util); + field->data.util = (void*)util; + field->data.free = &free_eas3; - /*--------------------------------------------------------*\ - ! 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; + /*--------------------------------------------------------*\ + ! Proceed according to the specified file operation marker.! + \*--------------------------------------------------------*/ + switch(*mode) + { + case 'r': + { + /*--------------------------------------------------------*\ + ! Verify that the field structure is not already set up to ! + ! read from a compressed file. ! + \*--------------------------------------------------------*/ + if((field->codestream.flag & CS_IN) != 0) + { + // invalid read operation + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Invalid setup |\n"\ + "| |\n"\ + "| The supplied bwc_field structure is already |\n"\ + "| set to read from a bwc file. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + free_eas3(field); + return EXIT_FAILURE; + } - if(data->info.parameter->precision == 4) - { + /*--------------------------------------------------------*\ + ! Append the suitable read function as well as the file ! + ! extension and set the IO flag for the numerical field. ! + \*--------------------------------------------------------*/ + field->data.IO = &read_eas3; + field->data.flag |= (DATA_IN | DATA_STR); + strncpy(info->file_ext, "eas3", 5); + + /*--------------------------------------------------------*\ + ! Open the specified file for reading and, if successful, ! + ! load the header information into the bwc data structure. ! + \*--------------------------------------------------------*/ + if((field->data.fp = 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); + free_eas3(field); + return EXIT_FAILURE; + } + + if(read_eas3_header(field)) + { + //error reading eas3 header + free_eas3(field); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Calculate and verify the size of the numerical dataset ! + ! and, if successful, allocate and initialize the array ! + ! used to store the parameter offset. ! + \*--------------------------------------------------------*/ + root = ftell(fp); + fseek(fp, 0L, SEEK_END); + Lfile = (ftell(fp) - root) / sizeof(double); + fseek(fp, root, SEEK_SET); + + Lfield = info->nX * info->nY * + info->nZ * info->nTS; + + if(Lfile != Lfield * info->numParams) + { + // error in file size + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Invalid size |\n"\ + "| |\n"\ + "| Number of bytes present in the dataset does |\n"\ + "| not match the specified dimensions, times- |\n"\ + "| steps and number of parameters. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + free_eas3(field); + return EXIT_FAILURE; + } + + util->offset = calloc(info->numParams, sizeof(uint64)); + if(util->offset == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free_eas3(field); + return EXIT_FAILURE; + } + + for(p = 0; p < info->numParams; ++p) + util->offset[p] = root + p * Lfield; + + break; + } + + case 'w': + { + /*--------------------------------------------------------*\ + ! Verify that field structure isn't already set to write ! + ! from a compressed file. ! + \*--------------------------------------------------------*/ + if((field->codestream.flag & CS_OUT) == 0) + { + // invalid read operation + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Invalid setup |\n"\ + "| |\n"\ + "| The current bwc_field structure is already |\n"\ + "| set to write to a bwc file. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + free_eas3(field); + return EXIT_FAILURE; + } + /*--------------------------------------------------------*\ + ! Append the suitable write function and set the IO flag ! + ! for the numerical field. ! + \*--------------------------------------------------------*/ + field->data.IO = &write_eas3; + field->data.flag |= (DATA_OUT | DATA_STR); + + /*--------------------------------------------------------*\ + ! Verify, that the codestream corresponds to a compressed ! + ! eas3 file. If successful, open the specified file ini- ! + ! tialize the array used to store the parameter offset. ! + \*--------------------------------------------------------*/ + if((field->data.fp = fp = fopen(filename, "wb")) == NULL) + { + // error opening file + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Could not open or read %-25s|\n"\ + "o##########################################################o\n", filename); + free_eas3(field); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! If a bwc codestream has been defined in the field struc- ! + ! ture, properly initialize the data file and data utility ! + ! structure. ! + \*--------------------------------------------------------*/ + if((field->codestream.flag & CS_IN) == 0) + { + /*--------------------------------------------------------*\ + ! If the user supplied codestream supports the file format ! + ! write the header information to file. ! + \*--------------------------------------------------------*/ + if(strcmp("eas3", field->info.file_ext)) + { + //File error + fprintf(stderr, FRMERROR); + return EXIT_FAILURE; + } + + if(write_eas3_header(field) == EXIT_FAILURE) + { + // invalid read + fprintf(stderr, WRTERROR); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Evaluate the parameter root and allocate and initialize ! + ! the parameter offset structure. ! + \*--------------------------------------------------------*/ + root = ftell(fp); + + util->offset = calloc(field->info.numParams, sizeof(uint64)); + if(util->offset == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + + for(p = 0; p < field->info.numParams; ++p) + { + for(param = info->parameter->root; param->id != p; param = param->next); + + if(p == 0) + { + util->offset[p] = root + (param->size * param->precision); + } + else + { + util->offset[p] = util->offset[p - 1] + (param->size * param->precision); + } + } + /*--------------------------------------------------------*\ + ! Modify the data flag to indicate that it has been init. ! + \*--------------------------------------------------------*/ + field->data.flag |= DATA_INI; + } + + break; + } + + default: + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Invalid File Operation |\n"\ + "o##########################################################o\n"); + free_eas3(field); + return EXIT_FAILURE; + } + } + + /*--------------------------------------------------------*\ + ! Return to function caller. ! + \*--------------------------------------------------------*/ + return EXIT_SUCCESS; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! | | ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! stream - ! +! ! +! RETURN: ! +! ------- ! +! Number of bites that have been written to the bitstream. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function opens an eas3 file, parses its header and checks the file for ! +! its validity. If verified, the numerical dataset is read from the file and, ! +! alongside the header information, stored in the bwc_field structure. ! +! In case of an error, the function will properly free the numerical dataset in ! +! the bwc_field structure and return an error flag to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining and control- ! +! ling a (de-)compression run. ! +! ! +! filename char* - Name of an eas3 file. ! +! ! +! 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. ! +! 12.03.2020 Patrick Vogler B87E7E4 V 0.1.0 refactored load fuction ! +! to define a unified in- ! +! terface for additional ! +! file formats. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +uchar +load_eas3(bwc_field *const field, + char const *const filename) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 parID; + uint64 parSize; + uint64 parOffset; + uint8 parPrec; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_inf *info; + bwc_cmd_opts_ll *param; + eas3_file_util *util; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar *data; + + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(filename); + + /*--------------------------------------------------------*\ + ! Open an eas3 file, parses its header and checks the file ! + ! for its validity. ! + \*--------------------------------------------------------*/ + if(open_eas3(field, filename, "r") == EXIT_FAILURE) + return EXIT_FAILURE; + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + info = &field->info; + + util = field->data.util; + fp = field->data.fp; + + /*--------------------------------------------------------*\ + ! Allocate the pointer array used to store the parameter ! + ! memory addresses. ! + \*--------------------------------------------------------*/ + field->data.body = calloc(info->numParams, sizeof(bwc_packed_stream)); + if(field->data.body == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free_eas3(field); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Evaluate the number of data samples per parameter, iter- ! + ! over all parameters in the dataset and load them into ! + ! memory. ! + \*--------------------------------------------------------*/ + parSize = info->nX * info->nY * info->nZ * info->nTS; + + for(param = info->parameter->root; param != NULL; param = param->next) + { /*--------------------------------------------------------*\ - ! Convert the flow field data from big endian to endian. ! + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! \*--------------------------------------------------------*/ - for(i = Lfield; i --> 0;) - { - endian_conversion(&data->field.f[i], 4); - } + parID = param->id; + parPrec = param->precision; + + parOffset = util->offset[parID]; /*--------------------------------------------------------*\ - ! Write the flow field data to the specified eas3 file. ! + ! Allocate the memory for the current parameter, advance ! + ! the file pointer to the proper position and load the ! + ! data samples into memory. ! \*--------------------------------------------------------*/ - 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); - } + data = calloc(parSize * param->precision, sizeof(uchar)); + if(data == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free_eas3(field); + return EXIT_FAILURE; + } + + fseek(fp, parOffset, SEEK_SET); + + if(fread(data, parPrec, parSize, fp) != parSize) + { + // invalid read + fprintf(stderr, RDERROR); + free_eas3(field); + free(data); + return EXIT_FAILURE; + } /*--------------------------------------------------------*\ - ! Write the flow field data to the specified eas3 file. ! + ! Properly set up the packed data stream corresponding to ! + ! the user supplied ID and adjust the memory usage. ! \*--------------------------------------------------------*/ - if(fwrite(data->field.d, sizeof(double), Lfield, data->file.fp) != Lfield) - { - // invalid read - fprintf(stderr, WRTERROR); - return 1; - } - } + field->data.body[parID].param = parID; + field->data.body[parID].tile = 0; - /*--------------------------------------------------------*\ - ! Close the file pointer and return to the function caller.! - \*--------------------------------------------------------*/ - fclose(data->file.fp); - data->file.fp = NULL; - return 0; + field->data.body[parID].access = + field->data.body[parID].memory = (uchar*)data; + field->data.body[parID].size = parSize * parPrec; + + field->data.count++; + + field->memory.usage.data += parSize * parPrec; + } + + /*--------------------------------------------------------*\ + ! Close the file pointer, adjust the data structure flag ! + ! and return to the function caller. ! + \*--------------------------------------------------------*/ + fclose(field->data.fp); + + field->data.flag ^= DATA_STR; + field->data.fp = NULL; + + return EXIT_SUCCESS; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! | | ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! stream - ! +! ! +! RETURN: ! +! ------- ! +! Number of bites that have been written to the bitstream. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function opens an eas3 file, parses its header and checks the file for ! +! its validity. If verified, the numerical dataset is read from the file and, ! +! alongside the header information, stored in the bwc_field structure. ! +! In case of an error, the function will properly free the numerical dataset in ! +! the bwc_field structure and return an error flag to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Structure defining and control- ! +! ling a (de-)compression run. ! +! ! +! filename char* - Name of an eas3 file. ! +! ! +! 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. ! +! 12.03.2020 Patrick Vogler B87E7E4 V 0.1.0 refactored load fuction ! +! to define a unified in- ! +! terface for additional ! +! file formats. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +uchar +unload_eas3(bwc_field *const field, + char const *const filename) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 parID; + uint64 parSize; + uint64 parOffset; + uint8 parPrec; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_inf *info; + bwc_cmd_opts_ll *param; + eas3_file_util *util; + + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(filename); + + /*--------------------------------------------------------*\ + ! Open and write the proper header to an eas3 file. ! + \*--------------------------------------------------------*/ + if(open_eas3(field, filename, "w") == EXIT_FAILURE) + return EXIT_FAILURE; + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + info = &field->info; + + util = field->data.util; + fp = field->data.fp; + + /*--------------------------------------------------------*\ + ! Loop through the parameters and write their respective ! + ! samples to the specified file. ! + \*--------------------------------------------------------*/ + for(param = info->parameter->root; param != NULL; param = param->next) + { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + parOffset = util->offset[parID]; + + parID = param->id; + parPrec = param->precision; + parSize = param->size; + + /*--------------------------------------------------------*\ + ! Advance the file pointer to the proper position and un- ! + ! load the parameter data samples to file. ! + \*--------------------------------------------------------*/ + fseek(fp, parOffset, SEEK_SET); + + if(fwrite(&field->data.body[parID].memory, parSize, parPrec, fp) != parSize) + { + // invalid write + fprintf(stderr, WRTERROR); + return EXIT_FAILURE; + } + } + /*--------------------------------------------------------*\ + ! Close the file pointer, adjust the data structure flag ! + ! and return to the function caller. ! + \*--------------------------------------------------------*/ + fclose(field->data.fp); + + field->data.flag ^= DATA_STR; + field->data.fp = NULL; + + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/src/interfaces/reader/netCDF.c b/src/interfaces/reader/netCDF.c new file mode 100755 index 0000000..3471bff --- /dev/null +++ b/src/interfaces/reader/netCDF.c @@ -0,0 +1,1115 @@ +/*====================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This file defines simple read and write functions used to access conforming || +|| netCDF datasets. || +|| || +|| ---------------------------------------------------------------------------------------------------------------- || +|| || +|| 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. || +|| || +\*====================================================================================================================*/ +/************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\************************************************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#include "utilities/utilities.h" +#include "utilities/eas3.h" + +/************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! 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. ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +get_attributes(bwc_stream *const aux, const int ncId, const int varId, const int attrId) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int status; + uint16 Lchk; + size_t attr_len, attr_size; + nc_type attrTypeId; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char *attr = NULL, + *buffer = NULL; + + /*--------------------------------------------------------*\ + ! Allocate a character array used to get strings from the ! + ! specified data file. ! + \*--------------------------------------------------------*/ + buffer = calloc(NC_MAX_ATTRS, sizeof(uchar)); + if(!buffer) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(buffer); + return 1; + } + + /*--------------------------------------------------------*\ + ! Read the attribute name from the data file. ! + \*--------------------------------------------------------*/ + if((status = nc_inq_attname(ncId, varId, attrId, buffer))) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + free(buffer); + return 1; + } + + /*--------------------------------------------------------*\ + ! Read the attribute type and length from the data file. ! + \*--------------------------------------------------------*/ + if((status = nc_inq_att(ncId, varId, buffer, &attrTypeId, &attr_len))) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + free(buffer); + return 1; + } + + /*--------------------------------------------------------*\ + ! Calculate the attribute size with regard to its specif- ! + ! ied type. ! + \*--------------------------------------------------------*/ + switch(attrTypeId) + { + case NC_BYTE: + case NC_UBYTE: + case NC_CHAR: + case NC_STRING: + { + attr_size = attr_len + 1; + break; + } + + case NC_SHORT: + case NC_USHORT: + { + attr_size = (attr_len * 2) + 1; + break; + } + + case NC_INT: + case NC_UINT: + case NC_FLOAT: + { + attr_size = (attr_len * 4) + 1; + break; + } + + case NC_INT64: + case NC_UINT64: + case NC_DOUBLE: + { + attr_size = (attr_len * 8) + 1; + break; + } + } + + /*--------------------------------------------------------*\ + ! Allocate a character array used to store the attribute ! + ! value and null terminate it. ! + \*--------------------------------------------------------*/ + attr = calloc(1, attr_size); + if(!attr) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(buffer); + return 1; + } + + /*--------------------------------------------------------*\ + ! Read the attribute type and length from the data file. ! + \*--------------------------------------------------------*/ + if((status = nc_get_att(ncId, varId, buffer, attr))) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + free(buffer); + free(attr); + return 1; + } + + /*--------------------------------------------------------*\ + ! Store the attribute name, value, type and length in the ! + ! auxiliary bitstream. ! + \*--------------------------------------------------------*/ + Lchk = (uint16)strlen(buffer); + emit_symbol(aux, Lchk, 2); + emit_chunck(aux, (uchar*)buffer, Lchk); + + Lchk = (uint16)strlen(attr); + emit_symbol(aux, Lchk, 2); + emit_chunck(aux, (uchar*)attr, Lchk); + + emit_symbol(aux, attrTypeId, sizeof(nc_type)); + emit_symbol(aux, attr_len, sizeof(size_t)); + + /*--------------------------------------------------------*\ + ! Free the attribute character array and return to the ! + ! function caller. ! + \*--------------------------------------------------------*/ + free(buffer); + free(attr); + 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. ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +put_attributes(bwc_stream *const aux, const int ncId, const int varId) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int status; + uint16 Lchk; + size_t attr_len; + nc_type attrTypeId; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char *attr = NULL, + *buffer = NULL; + + /*--------------------------------------------------------*\ + ! Get the attribute name, value, type and length in the ! + ! auxiliary bitstream. ! + \*--------------------------------------------------------*/ + Lchk = (uint16)get_symbol(aux, 2); + buffer = (char*)get_chunck(aux, Lchk); + + Lchk = (uint16)get_symbol(aux, 2); + attr = (char*)get_chunck(aux, Lchk); + + attrTypeId = (nc_type)get_symbol(aux, sizeof(nc_type)); + attr_len = (size_t)get_symbol(aux, sizeof(size_t)); + + /*--------------------------------------------------------*\ + ! Write the attribute name to the data file. ! + \*--------------------------------------------------------*/ + if((status = nc_put_att(ncId, varId, buffer, attrTypeId, attr_len, attr))) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + free(buffer); + return 1; + } + + /*--------------------------------------------------------*\ + ! Free the attribute character array and return to the ! + ! function caller. ! + \*--------------------------------------------------------*/ + free(buffer); + free(attr); + 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_netCDF(char *const filename) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 Lfield; + uint64 l; + int i, j, k; + int nVarDims, varDimsId, nVarAttr; + int nDims, nUDims; + int nVar, nAttr; + int ncId; + int status; + uint16 Lchk; + size_t *start, *count; + size_t len; + nc_type varTypeId; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char *buffer = NULL; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_data *file; + bwc_data_inf *info; + bwc_stream *aux; + + /*--------------------------------------------------------*\ + ! Open the specified file for reading. If the file doesn't ! + ! exist, exit the bwc command-line tool. ! + \*--------------------------------------------------------*/ + if((status = nc_open(filename, NC_NOWRITE, &ncId))) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Allocate the data structure. ! + \*--------------------------------------------------------*/ + file = calloc(1, sizeof(bwc_data)); + if(!file) + { + // memory allocation error + fprintf(stderr, MEMERROR); + nc_close(ncId); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + info = &file->info; + + /*--------------------------------------------------------*\ + ! Allocate the auxiliary information packed stream. ! + \*--------------------------------------------------------*/ + file->aux = calloc(1, sizeof(bwc_packed_stream)); + if(!file->aux) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + nc_close(ncId); + return NULL; + } + + /*--------------------------------------------------------*\ + ! 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 = init_stream(NULL, AUX_SIZE, 'c'); + if(!aux) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + nc_close(ncId); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Extract the number of dimensions, parameters, attributes ! + ! and "unlimited dimensions" from the specified netCDF ! + ! file. ! + \*--------------------------------------------------------*/ + if((status = nc_inq(ncId, &nDims, &nVar, &nAttr, &nUDims))) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + bwc_free_data(file); + nc_close(ncId); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Safe the number of variables and global attributes in ! + ! the auxiliary information memory block. ! + \*--------------------------------------------------------*/ + emit_symbol(aux, nVar, sizeof(int)); + emit_symbol(aux, nAttr, sizeof(int)); + + /*--------------------------------------------------------*\ + ! Allocate a start and count array for the dimensions spe- ! + ! cified in the data file. ! + \*--------------------------------------------------------*/ + start = calloc(4, sizeof(size_t)); + count = calloc(4, sizeof(size_t)); + if(!start || !count) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + nc_close(ncId); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Check if the number of specified dimensions does not ! + ! exceed the number of supported dimensions. ! + \*--------------------------------------------------------*/ + if(nDims > 4) + { + // error in number of dimensions + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Number of dimensions present in the input file is |\n"\ + "| larger than the number of supported dimensions. |\n"\ + "o##########################################################o\n"); + bwc_free_data(file); + nc_close(ncId); + free(start); + free(count); + return NULL; + } + else + { + /*--------------------------------------------------------*\ + ! Allocate a character array used to get strings from the ! + ! specified data file. ! + \*--------------------------------------------------------*/ + buffer = calloc(NC_MAX_NAME, sizeof(char)); + if(!buffer) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + nc_close(ncId); + free(start); + free(count); + return NULL; + } + + for(i = 0; i < nDims; ++i) + { + /*--------------------------------------------------------*\ + ! Get the dimension name and length for the 1st dimension. ! + \*--------------------------------------------------------*/ + if((status = nc_inq_dim(ncId, i, buffer, &len))) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + bwc_free_data(file); + nc_close(ncId); + free(buffer); + free(start); + free(count); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Safe the dimension name in the auxiliary information mem-! + ! ory block and reset the buffer character array. ! + \*--------------------------------------------------------*/ + Lchk = (uint16)strlen(buffer); + emit_symbol(aux, Lchk, 2); + emit_chunck(aux, (uchar*)buffer, Lchk); + + memset(buffer, '\0', NC_MAX_NAME); + + /*--------------------------------------------------------*\ + ! Set up the start and count for the current dimension. ! + \*--------------------------------------------------------*/ + start[i] = 0; + count[i] = len; + } + + /*--------------------------------------------------------*\ + ! Free the buffer character array. ! + \*--------------------------------------------------------*/ + free(buffer); + } + + /*--------------------------------------------------------*\ + ! Update the file info structure with the appropriate val- ! + ! ues and calculate the size of a variable. ! + \*--------------------------------------------------------*/ + info->nX = (count[0] == 0) ? 1 : count[0]; + info->nY = (count[1] == 0) ? 1 : count[1]; + info->nZ = (count[2] == 0) ? 1 : count[2]; + info->nTS = (count[3] == 0) ? 1 : count[3]; + + Lfield = info->nX * info->nY * info->nZ * info->nTS; + + /*--------------------------------------------------------*\ + ! Reallocate a start and count array for the dimensions to ! + ! fit the number of dimensions specified in the data file. ! + \*--------------------------------------------------------*/ + start = realloc(start, nDims * sizeof(size_t)); + count = realloc(count, nDims * sizeof(size_t)); + if(!start || !count) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + nc_close(ncId); + return NULL; + } + + /*--------------------------------------------------------*\ + ! If the bwc_add_param function is called for the first ! + ! time, allocate the parameter structure and parameter ! + ! name character array. ! + \*--------------------------------------------------------*/ + info->param_name = calloc(nVar, sizeof(char*)); + if(!info->param_name) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + nc_close(ncId); + free(start); + free(count); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Get the global attributes from the specified data file ! + ! and store their values in the auxiliary information ! + ! blocks. ! + \*--------------------------------------------------------*/ + for(i = 0; i < nAttr; ++i) + { + if(get_attributes(aux, ncId, NC_GLOBAL, i)) + { + bwc_free_data(file); + nc_close(ncId); + free(start); + free(count); + return NULL; + } + } + + for(i = 0, k = 0; i < nVar; ++i) + { + /*--------------------------------------------------------*\ + ! Allocate a character array used to get strings from the ! + ! specified data file. ! + \*--------------------------------------------------------*/ + buffer = calloc(NC_MAX_NAME, sizeof(uchar)); + if(!buffer) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + nc_close(ncId); + free(start); + free(count); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Extract the variable name and type, number of dimensions ! + ! and number of attributes associated with the current var-! + ! iable id. ! + \*--------------------------------------------------------*/ + if((status = nc_inq_var(ncId, i, buffer, &varTypeId, + &nVarDims, + &varDimsId, + &nVarAttr))) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + bwc_free_data(file); + nc_close(ncId); + free(start); + free(count); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Store the number of dimensions and attributes as well as ! + ! the variable name and type for the current variable id ! + ! in the aux bitstream. ! + \*--------------------------------------------------------*/ + Lchk = (uint16)strlen(buffer); + emit_symbol(aux, Lchk, 2); + emit_chunck(aux, (uchar*)buffer, Lchk); + + emit_symbol(aux, varTypeId, sizeof(nc_type)); + emit_symbol(aux, nVarDims, sizeof(int)); + emit_symbol(aux, nVarAttr, sizeof(int)); + + if((varTypeId == NC_DOUBLE) && (nDims == nVarDims)) + { + /*--------------------------------------------------------*\ + ! Reallocate the character array to the required string ! + ! size. ! + \*--------------------------------------------------------*/ + info->param_name[k] = realloc(buffer, + (strlen(buffer) + 1) * sizeof(char)); + + file->field = realloc(file->field, (k + 1) * Lfield * sizeof(bwc_float)); + + if((status = nc_get_vara_double(ncId, i, start, count, file->field + (k * Lfield)))) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + bwc_free_data(file); + nc_close(ncId); + free(start); + free(count); + return NULL; + } + + k++; + } + else + { + free(buffer); + } + + + /*--------------------------------------------------------*\ + ! Get the variable attributes from the specified data file ! + ! and store their values in the auxiliary information ! + ! block. ! + \*--------------------------------------------------------*/ + for(j = 0; j < nVarAttr; ++j) + { + if(get_attributes(aux, ncId, i, j)) + { + bwc_free_data(file); + nc_close(ncId); + free(start); + free(count); + return NULL; + } + } + } + + /*--------------------------------------------------------*\ + ! Update the file info structure with the appropriate val- ! + ! ues. ! + \*--------------------------------------------------------*/ + info->nPar = k; + + /*--------------------------------------------------------*\ + ! Check for NaN cases. ! + \*--------------------------------------------------------*/ + for(l = 0; l < (k * Lfield); ++l) + { + if(isnan(file->field[l])) + { + file->field[l] = 0.f; + } + } + /*--------------------------------------------------------*\ + ! 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(terminate_stream(aux, file->aux) == FAILURE) + { + bwc_free_data(file); + nc_close(ncId); + free(start); + free(count); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Close the netCDF file and return the bwc_data structure ! + ! to the function caller. ! + \*--------------------------------------------------------*/ + nc_close(ncId); + free(start); + free(count); + return file; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! 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_netCDF(bwc_data *const file, char *const filename) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 Lfield; + int i, j, k; + int nVarDims, nVarAttr; + int nDims; + int nVar, nAttr; + int ncId, *dimId; + int varId, *varIdArr; + int status; + uint16 Lchk; + size_t *start, *count; + nc_type varTypeId; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char *buffer = NULL; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_data_inf *info; + bwc_stream *aux; + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + info = &file->info; + + /*--------------------------------------------------------*\ + ! Open the specified file for reading. If the file doesn't ! + ! exist, exit the bwc command-line tool. ! + \*--------------------------------------------------------*/ + if((status = nc_create(filename, NC_CLOBBER, &ncId))) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + return 1; + } + + /*--------------------------------------------------------*\ + ! Initialize the auxiliary information stream. ! + \*--------------------------------------------------------*/ + aux = init_stream(file->aux->memory, file->aux->size, 'd'); + + /*--------------------------------------------------------*\ + ! Get the number of variables and global attributes in the ! + ! auxiliary information memory block. ! + \*--------------------------------------------------------*/ + nVar = (int)get_symbol(aux, sizeof(int)); + nAttr = (int)get_symbol(aux, sizeof(int)); + + /*--------------------------------------------------------*\ + ! Calculate the size of the data field used for write oper-! + ! ations. ! + \*--------------------------------------------------------*/ + Lfield = info->nX * info->nY * + info->nZ * info->nTS; + + /*--------------------------------------------------------*\ + ! Allocate a start and count array for the dimensions spe- ! + ! cified in the data file. ! + \*--------------------------------------------------------*/ + start = calloc(4, sizeof(size_t)); + count = calloc(4, sizeof(size_t)); + if(!start || !count) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + nc_close(ncId); + return 1; + } + + /*--------------------------------------------------------*\ + ! Update the file info structure with the appropriate val- ! + ! ues and calculate the size of a variable. ! + \*--------------------------------------------------------*/ + count[0] = (info->nX >> 1) ? info->nX : 0; + count[1] = (info->nY >> 1) ? info->nY : 0; + count[2] = (info->nZ >> 1) ? info->nZ : 0; + count[3] = (info->nTS >> 1) ? info->nTS : 0; + + /*--------------------------------------------------------*\ + ! Calculate the number of dimensions that are present in ! + ! the compressed codestream. ! + \*--------------------------------------------------------*/ + nDims = (count[0] ? 1 : 0) + + (count[1] ? 1 : 0) + + (count[2] ? 1 : 0) + + (count[3] ? 1 : 0); + + /*--------------------------------------------------------*\ + ! Allocate a dimension id array. ! + \*--------------------------------------------------------*/ + dimId = calloc(nDims, sizeof(int)); + if(!dimId) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + nc_close(ncId); + free(start); + free(count); + return 1; + } + + /*--------------------------------------------------------*\ + ! Reallocate a start and count array for the dimensions to ! + ! fit the number of dimensions specified in the data file. ! + \*--------------------------------------------------------*/ + start = realloc(start, nDims * sizeof(size_t)); + count = realloc(count, nDims * sizeof(size_t)); + if(!start || !count) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + nc_close(ncId); + free(dimId); + return 1; + } + + for(i = 0; i < nDims; ++i) + { + /*--------------------------------------------------------*\ + ! Get the dimension name from the auxiliary information ! + ! memory block. ! + \*--------------------------------------------------------*/ + Lchk = (uint16)get_symbol(aux, 2); + buffer = (char*)get_chunck(aux, Lchk); + if(!buffer) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + nc_close(ncId); + free(start); + free(count); + free(dimId); + return 1; + } + + /*--------------------------------------------------------*\ + ! Define the dimension in the netCDF dataset. ! + \*--------------------------------------------------------*/ + if((status = nc_def_dim(ncId, buffer, count[i], &dimId[i]))) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + bwc_free_data(file); + nc_close(ncId); + free(buffer); + free(start); + free(count); + free(dimId); + return 1; + } + + /*--------------------------------------------------------*\ + ! Free the buffer character array. ! + \*--------------------------------------------------------*/ + free(buffer); + } + + /*--------------------------------------------------------*\ + ! Get the global attributes from the specified data file ! + ! and store their values in the auxiliary information ! + ! blocks. ! + \*--------------------------------------------------------*/ + for(i = 0; i < nAttr; ++i) + { + if(put_attributes(aux, ncId, NC_GLOBAL)) + { + bwc_free_data(file); + nc_close(ncId); + free(buffer); + free(start); + free(count); + free(dimId); + return 1; + } + } + + /*--------------------------------------------------------*\ + ! Allocate a dimension id array. ! + \*--------------------------------------------------------*/ + varIdArr = calloc(nVar, sizeof(int)); + if(!varIdArr) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + nc_close(ncId); + free(start); + free(count); + free(dimId); + return 1; + } + + for(i = 0, k = 0; i < nVar; ++i) + { + /*--------------------------------------------------------*\ + ! Get the number of dimensions and attributes as well as ! + ! the variable name and type for the current variable id ! + ! in the aux bitstream. ! + \*--------------------------------------------------------*/ + Lchk = (uint16)get_symbol(aux, 2); + buffer = (char*)get_chunck(aux, Lchk); + if(!buffer) + { + // memory allocation error + fprintf(stderr, MEMERROR); + bwc_free_data(file); + nc_close(ncId); + free(varIdArr); + free(start); + free(count); + free(dimId); + return 1; + } + + varTypeId = (nc_type)get_symbol(aux, sizeof(nc_type)); + nVarDims = (int)get_symbol(aux, sizeof(int)); + nVarAttr = (int)get_symbol(aux, sizeof(int)); + + /*--------------------------------------------------------*\ + ! Define the variable in the netCDF dataset. ! + \*--------------------------------------------------------*/ + if((status = nc_def_var(ncId, buffer, varTypeId, + nVarDims, + dimId, + &varId))) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + bwc_free_data(file); + nc_close(ncId); + free(varIdArr); + free(start); + free(count); + free(dimId); + return 1; + } + + /*--------------------------------------------------------*\ + ! Put the variable attributes from the specified data file ! + ! and store their values in the auxiliary information ! + ! block. ! + \*--------------------------------------------------------*/ + for(j = 0; j < nVarAttr; ++j) + { + if(put_attributes(aux, ncId, varId)) + { + bwc_free_data(file); + nc_close(ncId); + free(varIdArr); + free(start); + free(count); + free(dimId); + return 1; + } + } + + if((varTypeId == NC_DOUBLE) && (nDims == nVarDims)) + { + varIdArr[k] = varId; + k++; + } + + free(buffer); + } + + /*--------------------------------------------------------*\ + ! Deallocate a dimension id array. ! + \*--------------------------------------------------------*/ + free(dimId); + + /*--------------------------------------------------------*\ + ! Leave define mode to create the variable. ! + \*--------------------------------------------------------*/ + if((status = nc_enddef(ncId))) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + bwc_free_data(file); + nc_close(ncId); + free(varIdArr); + free(start); + free(count); + free(dimId); + return 1; + } + + for(i = 0; i < k; ++i) + { + /*--------------------------------------------------------*\ + ! Define the variable in the netCDF dataset. ! + \*--------------------------------------------------------*/ + if((status = nc_put_vara(ncId, varIdArr[i], start, count, file->field + (i * Lfield)))) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + bwc_free_data(file); + nc_close(ncId); + free(start); + free(count); + free(dimId); + return 1; + } + } + + /*--------------------------------------------------------*\ + ! Free the auxiliary information stream and variable id ! + ! array. ! + \*--------------------------------------------------------*/ + free(varIdArr); + free(aux); + + /*--------------------------------------------------------*\ + ! Close the netCDF file and return the bwc_data structure ! + ! to the function caller. ! + \*--------------------------------------------------------*/ + nc_close(ncId); + free(start); + free(count); + return 0; +} \ No newline at end of file diff --git a/src/library/CMakeLists.txt b/src/library/CMakeLists.txt index 43ae796..31bebf8 100755 --- a/src/library/CMakeLists.txt +++ b/src/library/CMakeLists.txt @@ -1,57 +1,49 @@ -#*====================================================================================================================*# -#| |# -#| /$$$$$$$ /$$ /$$ /$$ /$$ |# -#| | $$__ $$|__/ | $$ /$ | $$| $$ |# -#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# -#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# -#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# -#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# -#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# -#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# -#| /$$ \ $$ | $$ |# -#| | $$$$$$/ | $$ |# -#| \______/ |__/ |# -#| 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. |# -#| |# -#*====================================================================================================================*# -#*--------------------------------------------------------*# +#*================================================================================================*# +#| |# +#| /$$$$$$$ /$$ /$$ /$$ /$$ |# +#| | $$__ $$|__/ | $$ /$ | $$| $$ |# +#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# +#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# +#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# +#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# +#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# +#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# +#| /$$ \ $$ | $$ |# +#| | $$$$$$/ | $$ |# +#| \______/ |__/ |# +#| |# +#| DESCRIPTION: |# +#| ------------ |# +#| |# +#| Defines the cmake script for the libbwc library. |# +#| |# +#| -------------------------------------------------------------------------------------------- |# +#| 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. |# +#| |# +#*================================================================================================*# +#----------------------------------------------------------# # Assemble the public header for the BigWhoop library # -#*--------------------------------------------------------*# +#----------------------------------------------------------# set(PYTHON_ARGUMENT "") if("${CMAKE_BUILD_TYPE}" STREQUAL "Release") @@ -67,60 +59,70 @@ 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) +add_library(bwclib ${BWC_LINK} bitstream.c + codestream.c + dwt.c + ../interfaces/reader/eas3.c + field.c + mq.c + libbwc.c + #netCDF.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) + target_compile_definitions(bwclib PRIVATE -DBWC_SINGLE_PRECISION) else() - target_compile_definitions(bwclib PRIVATE -DBWC_DOUBLE_PRECISION) + target_compile_definitions(bwclib PRIVATE -DBWC_DOUBLE_PRECISION) endif() -#*--------------------------------------------------------*# +#----------------------------------------------------------# +# Set the target compile definition for the requested file # +# format support. # +#----------------------------------------------------------# +if("${BUILD_EAS3}" STREQUAL "True") + target_compile_definitions(bwclib PRIVATE -DBWC_EAS3) +endif() + +if("${BUILD_NETCDF}" STREQUAL "True") + target_compile_definitions(bwclib PRIVATE -DBWC_NETCDF) +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) +target_include_directories(bwclib PRIVATE ${CMAKE_SOURCE_DIR}/include/interfaces/reader) -#*--------------------------------------------------------*# +#----------------------------------------------------------# # 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 +#----------------------------------------------------------# +set_property(TARGET bwclib PROPERTY OUTPUT_NAME bwc) diff --git a/src/library/bitstream.c b/src/library/bitstream.c index c38201d..c9fad1e 100755 --- a/src/library/bitstream.c +++ b/src/library/bitstream.c @@ -1,558 +1,624 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ - -/************************************************************************************************************\ -|| _ _ _ ____ _ _ _ ___ ____ || -|| | |\ | | | | | | \ |___ || -|| | | \| |___ |___ |__| |__/ |___ || -|| || -\************************************************************************************************************/ +/*====================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| 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 codestream and can emit/extract information on a per bit, symbol || +|| (64-bit) or string basis. || +|| || +|| ---------------------------------------------------------------------------------------------------------------- || +|| || +|| 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. || +|| || +\*====================================================================================================================*/ +/**********************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\**********************************************************************************************************************/ #include #include #include #include -#include "libbwc.h" +#include "macros.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. ! -! ! -! 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) +/**********************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to evaluate the number of bytes that have already been written ! +! to the allocated bitstream memory block. ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! stream - Structure used to assemble a bwc ! +! bitstream. ! +! ! +! RETURN: ! +! ------- ! +! Number of bites that have been written to the bitstream. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Release Description ! +! ---- ------ ------- ----------- ! +! 13.05.2019 Patrick Vogler V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +uint64 +bytes_used(bwc_stream const *const stream) { - if(stream->T == 0xFF) - { + if(stream->T == 0xFF) + { return stream->L + 1; - } - else - { + } + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function initializes a bwc bitstream. For encoding, a null pointer needs to be ! +! passed as a memory handle and the function will allocate a memory block with 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. ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! | | ! +! size - Initial size of the bwc stream. ! +! ! +! memory - Memory handle for the bwc strean ! +! memory block. ! +! ! +! instr - Constant used to instruct the ! +! field initialization. ! +! ! +! RETURN: ! +! ------- ! +! DESCRIPTION NEEDED ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Release Description ! +! ---- ------ ------- ----------- ! +! **.**.**** * V **.**.** Constant created. ! +! **.**.**** * V **.**.** Function created. ! +! **.**.**** * V **.**.** Macro created. ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function initializes a bwc bitstream. For encoding, a null pointer needs to ! +! be passed as a memory handle and the function will allocate a memory block with ! +! 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 uchar - Memory handle for the bwc strean ! +! memory block. ! +! ! +! instr char - Constant used to instruct the ! +! field initialization. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! stream - Structure used to assemble/ ! +! read a bwc bitstream. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 19.06.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ bwc_stream* -bwc_init_stream(uchar* memory, uint32 size, char instr) +init_stream(uchar *const memory, + uint32 const size, + char const instr) { - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_stream *stream; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_stream *stream; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(instr == 'c' || instr == 'd'); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(instr == 'c' || instr == 'd'); - /*--------------------------------------------------------*\ - ! Allocate the bwc stream structure. ! - \*--------------------------------------------------------*/ - stream = calloc(1, sizeof(bwc_stream)); - if(!stream) - { + /*--------------------------------------------------------*\ + ! Allocate the bwc stream structure. ! + \*--------------------------------------------------------*/ + stream = calloc(1, sizeof(bwc_stream)); + if(stream == NULL) + { // 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. ! - \*--------------------------------------------------------*/ + /*--------------------------------------------------------*\ + ! If verified that no memory handle has been passend, al- ! + ! locate a memory block with the proper size. Otherwise ! + ! save the memory handle in the bwc_stream structure. ! + \*--------------------------------------------------------*/ + if(memory == NULL) + { + stream->memory = calloc(size, sizeof(uchar)); + if(stream->memory == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return NULL; + } + } + else + { 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; + /*--------------------------------------------------------*\ + ! Initialize the byte buffer counter, stream size and size ! + ! increment for the current stream and return the stream ! + ! to the function caller. ! + \*--------------------------------------------------------*/ + stream->t = (instr == 'c') ? 8 : 0; + stream->Lmax = size; + stream->size_incr = (uint64)(size / 2); + + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! * * ! +! ! +! RETURN: ! +! ------- ! +! DESCRIPTION NEEDED ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Release Description ! +! ---- ------ ------- ----------- ! +! **.**.**** * V **.**.** Constant created. ! +! **.**.**** * V **.**.** Function created. ! +! **.**.**** * V **.**.** Macro created. ! +! | | ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to write a data block of size length to a bwc bitstream. ! +! In case of an error, the corresponding flag is set to true (= 1) and the stream ! +! length set to zero. If the error flag is already set the function returns to ! +! function caller without further action. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure used to assemble/read ! +! a bwc bitstream. ! +! ! +! chunck uchar* - Memory handle for a data block ! +! that is to be written to the bwc ! +! bwc bitstream. ! +! ! +! size unsigned int(64 bit) - Size of the data block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 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) +emit_chunck(bwc_stream *const stream, + uchar const *const chunck, + uint64 const size) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 Lreq; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 Lreq; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(stream); - assert(chunck); + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar *tmp; - /*--------------------------------------------------------*\ - ! Evaluate the memory block size if the current chunck of ! - ! data is written to the stream. ! - \*--------------------------------------------------------*/ - Lreq = (bytes_used(stream) + size); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + assert(chunck); - /*--------------------------------------------------------*\ - ! Check if the enough memory has been allocated for the ! - ! stream to store the additional data chunck. ! - \*--------------------------------------------------------*/ - if(Lreq > stream->Lmax) - { + /*--------------------------------------------------------*\ + ! Evaluate the memory block size after the current data ! + ! chunk has been written to the stream. Verify, that the ! + ! stream is large enough to store the additional data. ! + \*--------------------------------------------------------*/ + Lreq = (bytes_used(stream) + size); + + 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 the stream is not large enough, check if that is due ! + ! to a previous error. If not, increase the stream size ! + ! until it is large enough. Otherwise return to f. caller. ! \*--------------------------------------------------------*/ - 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); - } + if(stream->error == 0) + { + 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; - } - } + tmp = realloc(stream->memory, stream->Lmax); + if(tmp == NULL) + { + // memory allocation error + stream->error |= 1; + stream->Lmax = 0; + return; + } + else + { + stream->memory = tmp; + } + } else - { - /*--------------------------------------------------------*\ - ! Exit to function caller if error flag has been set. ! - \*--------------------------------------------------------*/ - return; - } - } + { + 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; + /*--------------------------------------------------------*\ + ! Copy the additional data to the stream memory block and ! + ! increase the stream size by the number of bytes written. ! + \*--------------------------------------------------------*/ + memcpy(stream->memory + stream->L, chunck, size); + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! * * ! +! ! +! RETURN: ! +! ------- ! +! DESCRIPTION NEEDED ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Release Description ! +! ---- ------ ------- ----------- ! +! **.**.**** * V **.**.** Constant created. ! +! **.**.**** * V **.**.** Function created. ! +! **.**.**** * V **.**.** Macro created. ! +! | | ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to write a symbol with max. 8 bytes to a bwc bitstream. In ! +! case of an error, the corresponding flag is set to true (= 1) and the stream ! +! length set to zero. If the error flag is already set the function returns to ! +! function caller without further action. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure used to assemble/read ! +! a bwc bitstream. ! +! ! +! symbol unsigned int(64 bit) - Symbol that is to be written to ! +! the bwc bitstream. ! +! ! +! size unsigned int(8 bit) - Number of bytes in the symbol. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 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) +emit_symbol(bwc_stream *const stream, + uint64 const symbol, + uint8 const size) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint8 byte; - int8 i; + /*-----------------------*\ + ! 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) - { + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar *tmp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + + /*--------------------------------------------------------*\ + ! Evaluate the memory block size after the current data ! + ! chunk has been written to the stream. Verify, that the ! + ! stream is large enough to store the additional data. ! + \*--------------------------------------------------------*/ + 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 the stream is not large enough, check if that is due ! + ! to a previous error. If not, increase the stream size. ! + ! Otherwise return to function caller. ! \*--------------------------------------------------------*/ - 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); + if(stream->error == 0) + { + 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; - } - } + tmp = realloc(stream->memory, stream->Lmax); + if(tmp == NULL) + { + // memory allocation error + stream->error |= 1; + stream->Lmax = 0; + return; + } + else + { + stream->memory = tmp; + } + } else - { - /*--------------------------------------------------------*\ - ! Exit to function caller if error flag has been set. ! - \*--------------------------------------------------------*/ - return; - } - } + { + 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;) - { + /*--------------------------------------------------------*\ + ! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! * * ! +! ! +! RETURN: ! +! ------- ! +! DESCRIPTION NEEDED ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Release Description ! +! ---- ------ ------- ----------- ! +! **.**.**** * V **.**.** Constant created. ! +! **.**.**** * V **.**.** Function created. ! +! **.**.**** * V **.**.** Macro created. ! +! | | ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to write a bit to a bwc bitstream. The bit is cached in a ! +! buffer until enough bits have been accumulated to fill one byte. The buffer is ! +! then written to the stream and the bit buffer set to zero. If the previous ! +! buffer had a value of 255, the subsequent buffer will be limited to 7 bits to ! +! ensure that the values in the range of 0xFFFF to 0xFF80 are reserved for ! +! codestream markers. ! +! In case of an error, the corresponding flag is set to true (= 1) and the stream ! +! length set to zero. If the error flag is already set the function returns to ! +! function caller without further action. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure used to assemble/read ! +! a bwc 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 ! +! ---- ------ --------- ------- ----------- ! +! 22.06.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ void -bwc_emit_bit(bwc_stream *const stream, const uint64 bit) +emit_bit(bwc_stream *const stream, + uint64 const bit) { - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(stream); - - /*--------------------------------------------------------*\ - ! Decrement the bit buffer counter. ! - \*--------------------------------------------------------*/ - stream->t--; + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar *tmp; - /*--------------------------------------------------------*\ - ! If the bit is significant, store the information at the ! - ! appropriate position in the bit buffer. ! - \*--------------------------------------------------------*/ - if(bit) - { - stream->T |= (1 << stream->t); - } + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); - /*--------------------------------------------------------*\ - ! 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. ! - \*--------------------------------------------------------*/ + /*--------------------------------------------------------*\ + ! Decrement the bit buffer counter and, if the bit is sig- ! + ! nificant, store the information in the bit buffer. ! + \*--------------------------------------------------------*/ + stream->t--; + + if(bit != 0) + stream->T |= (1 << stream->t); + + /*--------------------------------------------------------*\ + ! Check if the bit buffer is full. If true, evaluate the ! + ! memory block size after the byte has been written to the ! + ! stream and verify, that the stream is large enough. ! + \*--------------------------------------------------------*/ + if(stream->t == 0x0) + { 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) + { + /*--------------------------------------------------------*\ + ! If the stream is not large enough, check if that is due ! + ! to a previous error. If not, increase the stream size. ! + ! Otherwise return to function caller. ! + \*--------------------------------------------------------*/ + if(stream->error == 0) { - // memory allocation error - stream->error |= 1; - stream->Lmax = 0; - return; + stream->Lmax += stream->size_incr; + stream->size_incr = (uint64)(stream->Lmax / 2); + + tmp = realloc(stream->memory, stream->Lmax); + if(tmp == NULL) + { + // memory allocation error + stream->error |= 1; + stream->Lmax = 0; + return; + } + else + { + stream->memory = tmp; + } } - } - else - { - /*--------------------------------------------------------*\ - ! Exit to function caller if error flag has been set. ! - \*--------------------------------------------------------*/ - return; - } - } + else + { + return; + } + } /*--------------------------------------------------------*\ ! Copy the additional byte to the stream memory block and ! @@ -561,461 +627,688 @@ bwc_emit_bit(bwc_stream *const stream, const uint64 bit) 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. ! + ! Reset the bit buffer and buffer counter. If the current ! + ! buffer has a value of 255, limit the counter to 7 bits ! + ! to ensure the uniqueness of the stream markers. ! \*--------------------------------------------------------*/ if(stream->T == 0xFF) - { - stream->t = 7; - } + { + stream->t = 7; + } else - { - stream->t = 8; - } + { + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! * * ! +! ! +! RETURN: ! +! ------- ! +! DESCRIPTION NEEDED ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Release Description ! +! ---- ------ ------- ----------- ! +! **.**.**** * V **.**.** Constant created. ! +! **.**.**** * V **.**.** Function created. ! +! **.**.**** * V **.**.** Macro created. ! +! | | ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! ! +! This function is used to flush any remaining information stored in the bit ! +! buffer to the stream. ! +! In case of an error, the corresponding flag is set to true (= 1) and the stream ! +! length set to zero. If the error flag is already set the function returns to ! +! function caller without further action. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure used to assemble/read ! +! a bwc bitstream. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 30.06.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ void flush_stream(bwc_stream *const stream) { - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(stream); + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar *tmp; - /*--------------------------------------------------------*\ - ! 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. ! - \*--------------------------------------------------------*/ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + + /*--------------------------------------------------------*\ + ! Check if the bit buffer contains information. If true, ! + ! verify that the stream is large enough to accommodate ! + ! the additional information. ! + \*--------------------------------------------------------*/ + if(stream->t != 8) + { 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) + { + /*--------------------------------------------------------*\ + ! If the stream is not large enough, check if that is due ! + ! to a previous error. If not, increase the stream size. ! + ! Otherwise return to function caller. ! + \*--------------------------------------------------------*/ + if(stream->error == 0x0) { - // memory allocation error - stream->error |= 1; - stream->Lmax = 0; - return; + stream->Lmax += stream->size_incr; + stream->size_incr = (uint64)(stream->Lmax / 2); + + tmp = realloc(stream->memory, stream->Lmax); + if(tmp == NULL) + { + // memory allocation error + stream->error |= 1; + stream->Lmax = 0; + return; + } + else + { + stream->memory = tmp; + } } - } - else - { - /*--------------------------------------------------------*\ - ! Exit to function caller if error flag has been set. ! - \*--------------------------------------------------------*/ - return; - } - } + else + { + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! * * ! +! ! +! RETURN: ! +! ------- ! +! DESCRIPTION NEEDED ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Release Description ! +! ---- ------ ------- ----------- ! +! **.**.**** * V **.**.** Constant created. ! +! **.**.**** * V **.**.** Function created. ! +! **.**.**** * V **.**.** Macro created. ! +! | | ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to read a data block of size length from a bwc bitstream. ! +! In case of an error, the corresponding flag is set to true (= 1), the stream ! +! size set to zero and a NULL pointer is returned to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure used to assemble/read ! +! a bwc bitstream. ! +! ! +! size unsigned int(64 bit) - Size of the data block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar* - Memory handle to data block ! +! requested by function caller. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 22.06.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 07.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Proper error handling. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +uchar* +get_chunck(bwc_stream *const stream, + uint64 const size) +{ + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar *tmp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + + /*--------------------------------------------------------*\ + ! Check if the number of bytes to be read from the stream ! + ! do not exceed the number of bytes still present in its ! + ! memory block. ! + \*--------------------------------------------------------*/ + if(bytes_used(stream) + size <= stream->Lmax) + { + /*--------------------------------------------------------*\ + ! Allocate a memory block used to store the bytes extract- ! + ! ed from the stream. ! + \*--------------------------------------------------------*/ + tmp = calloc(size, sizeof(uchar)); + if(tmp == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Copy the requested data chunk to the allocated memory ! + ! block and increment the number of bytes read from the ! + ! stream. Return the memory handle to the function caller. ! + \*--------------------------------------------------------*/ + memcpy(tmp, stream->memory + stream->L, size); + stream->L += size; + + return tmp; + } + else + { + /*--------------------------------------------------------*\ + ! If the requested block size exceeds the information left ! + ! in the bitstream, set the bitstream error flag to 1, the ! + ! stream size to zero and return a NULL pointer. ! + \*--------------------------------------------------------*/ + stream->error |= 1; + stream->Lmax = 0; + return NULL; + } +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! * * ! +! ! +! RETURN: ! +! ------- ! +! DESCRIPTION NEEDED ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Release Description ! +! ---- ------ ------- ----------- ! +! **.**.**** * V **.**.** Constant created. ! +! **.**.**** * V **.**.** Function created. ! +! **.**.**** * V **.**.** Macro created. ! +! | | ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to read a symbol with max. 8 bytes from a bwc bitstream. ! +! In case of an error, the corresponding flag is set to true (= 1), the stream ! +! size set to zero and a NULL pointer is returned to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure used to assemble/read ! +! a bwc bitstream. ! +! ! +! size unsigned int(8 bit) - Number of bytes in the symbol. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! symbol - Symbol requested by function ! +! caller. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 22.06.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 07.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Proper error handling. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +uint64 +get_symbol(bwc_stream *const stream, + uint8 const 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 ! + ! do not exceed the number of bytes still present in its ! + ! memory block. ! + \*--------------------------------------------------------*/ + if(bytes_used(stream) + size <= stream->Lmax) + { + /*--------------------------------------------------------*\ + ! Extract the requested information one byte ate a time ! + ! increment the number of bytes read from the stream ac- ! + ! cordingly. Return the symbol to the function caller. ! + \*--------------------------------------------------------*/ + for(i = size, symbol = 0; i --> 0;) + { + byte = (uint8)stream->memory[stream->L++]; + symbol |= ((uint64)byte << (i * 8)); + } + + return symbol; + } + else + { + /*--------------------------------------------------------*\ + ! If the symbol size exceeds the information left in the ! + ! bitstream, set the bitstream error flag to 1, the stream ! + ! size to zero and return a NULL pointer. ! + \*--------------------------------------------------------*/ + stream->error |= 1; + stream->Lmax = 0; + return 0; + } +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! * * ! +! ! +! RETURN: ! +! ------- ! +! DESCRIPTION NEEDED ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Release Description ! +! ---- ------ ------- ----------- ! +! **.**.**** * V **.**.** Constant created. ! +! **.**.**** * V **.**.** Function created. ! +! **.**.**** * V **.**.** Macro created. ! +! | | ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to read a bit from a bwc bitstream. The bit is cached in ! +! a buffer until a request is made by function caller. If all bits have been read ! +! from the buffer, a new byte is extracted from the stream and the buffer couner ! +! is reeinitialized. In case the previous buffer had a value of 255, the ! +! subsequent buffer will contain 7 bits to ensure that the values in the range of ! +! 0xFFFF to 0xFF80 are reserved for codestream markers. ! +! In case of an error, the corresponding flag is set to true (= 1), the stream ! +! size set to zero and a 0 is returned to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure used to assemble/read ! +! a bwc bitstream. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! bit - Bit requested by function cal- ! +! ler. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 22.06.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 07.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Proper error handling. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +uchar +get_bit(bwc_stream *const stream) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + + /*--------------------------------------------------------*\ + ! Check if the bit buffer is empty. If true, verify that ! + ! an additional byte can be read from the stream. ! + \*--------------------------------------------------------*/ + if(stream->t == 0x0) + { + if(stream->L + 1 <= stream->Lmax) + { + /*--------------------------------------------------------*\ + ! Reset the bit buffer counter according to the value of ! + ! the current buffer. ! + \*--------------------------------------------------------*/ + if(stream->T == 0xFF) + stream->t = 7; + else + stream->t = 8; + + stream->T = (uint16)stream->memory[stream->L++]; + } + else + { + /*--------------------------------------------------------*\ + ! If the symbol size exceeds the information left in the ! + ! bitstream, set the bitstream error flag to 1, the stream ! + ! size to zero and return a NULL pointer. ! + \*--------------------------------------------------------*/ + stream->error |= 1; + stream->Lmax = 0; + return 0; + } + } + /*--------------------------------------------------------*\ + ! Decrease bit buffer counter, read the next bit from the ! + ! buffer and return it to the function caller. ! + \*--------------------------------------------------------*/ + stream->t--; + + return ((stream->T & (1 << stream->t)) >> stream->t); +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! * * ! +! ! +! RETURN: ! +! ------- ! +! DESCRIPTION NEEDED ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Release Description ! +! ---- ------ ------- ----------- ! +! **.**.**** * V **.**.** Constant created. ! +! **.**.**** * V **.**.** Function created. ! +! **.**.**** * V **.**.** Macro created. ! +! | | ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to terminate a bwc stream. If a valid pointer is passed on ! +! on by the function caller, the overall size and memory handle of the stream is ! +! stored in the bwc_packed_stream structure. If a NULL pointer is passed to the ! +! function, the entire stream, including the memory block, is properly deallocated. ! +! If the error flag is set in the bwc_structure, all allocated memory is properly ! +! deallocated and an error flag is returned to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure used to assemble/read ! +! read a bwc bitstream. ! +! ! +! packed_stream bwc_packed_stream* - Structure used to store all ! +! necessary information of a ! +! packed stream. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uchar - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 09.03.2020 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 07.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Proper error handling. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ uchar -bwc_terminate_stream(bwc_stream *stream, bwc_packed_stream *const packed_stream) +terminate_stream(bwc_stream *stream, + bwc_packed_stream *const packed_stream) { - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(stream); + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar *tmp; - 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; - } - } + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); - 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; + /*--------------------------------------------------------*\ + ! If an error occurred during the streaming operations, ! + ! deallocate the entire bwc_stream structure and return an ! + ! error flag ! + \*--------------------------------------------------------*/ + if(stream->error == 1) + { + if(stream->memory != NULL) + free(stream->memory); + + free(stream); + stream = NULL; + + return EXIT_FAILURE; + } + else + { + /*--------------------------------------------------------*\ + ! Check If a NULL pointer is passed instead of a packed ! + ! stream, deallocate the bwc stream memory block. Other- ! + ! wise proceed accordingly. ! + \*--------------------------------------------------------*/ + if(packed_stream == NULL) + { + free(stream->memory); + } + else + { + /*--------------------------------------------------------*\ + ! If necessary, optimize the stream memory block size and ! + ! store the reading/writing position, overall size and ! + ! memory handle in the bwc_packed_stream structure. ! + \*--------------------------------------------------------*/ + if(stream->L != stream->Lmax) + { + stream->Lmax = stream->L; + tmp = realloc(stream->memory, stream->Lmax); + if(tmp == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(stream); + stream = NULL; + return EXIT_FAILURE; + } + else + { + stream->memory = tmp; + } + } + + packed_stream->memory = stream->memory; + packed_stream->access = stream->memory; + packed_stream->size = stream->L; + } + + /*--------------------------------------------------------*\ + ! Properly deallocate the bwc_stream structure and return ! + ! to function caller. ! + \*--------------------------------------------------------*/ + free(stream); + stream = NULL; + + return EXIT_SUCCESS; + } } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! DESCRIPTION NEEDED ! +! ! +! ARGUMENTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! * * ! +! ! +! RETURN: ! +! ------- ! +! DESCRIPTION NEEDED ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Release Description ! +! ---- ------ ------- ----------- ! +! **.**.**** * V **.**.** Constant created. ! +! **.**.**** * V **.**.** Function created. ! +! **.**.**** * V **.**.** Macro created. ! +! | | ! +\*--------------------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to release all the information stored in a packed ! +! bitstream and reset the parameters for the next (de)compression run. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! packed_stream bwc_packed_stream* - Structure used to store all ! +! necessary information of a ! +! packed stream. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 22.06.2020 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ void -release_packed_stream(bwc_packed_stream *stream) +release_packed_stream(bwc_packed_stream *const stream) { - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(stream); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); - /*--------------------------------------------------------*\ - ! Free the data block of the packed bitstream. ! - \*--------------------------------------------------------*/ - free(stream->memory); + /*--------------------------------------------------------*\ + ! Free the memory block and reset all the parameters of ! + ! the packed stream. ! + \*--------------------------------------------------------*/ + free(stream->memory); - /*--------------------------------------------------------*\ - ! Reset all the packed stream parameters. ! - \*--------------------------------------------------------*/ - stream->access = NULL; - stream->position = 0; - stream->size = 0; + stream->memory = + stream->access = NULL; + stream->size = 0; } \ No newline at end of file diff --git a/src/library/codestream.c b/src/library/codestream.c index ab99f5e..8295903 100755 --- a/src/library/codestream.c +++ b/src/library/codestream.c @@ -1,1824 +1,2523 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ -/************************************************************************************************************\ -|| _ _ _ ____ _ _ _ ___ ____ || -|| | |\ | | | | | | \ |___ || -|| | | \| |___ |___ |__| |__/ |___ || -|| || -\************************************************************************************************************/ +/*====================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This file describes a set of function that can be used to create and manipulate a || +|| BigWhoop Codestream. They facilitate the assembly and parsing of the main header and || +|| tile bitsreams as well as read and write functions used to access conforming bwc || +|| datasets. || +|| || +|| ---------------------------------------------------------------------------------------------------------------- || +|| || +|| 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. || +|| || +\*====================================================================================================================*/ +/**********************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\**********************************************************************************************************************/ #include +#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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +#include "bitstream.h" +#include "macros.h" +#include "types.h" + +/**********************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to check if a memory block of a certain length can be ! +! read from a stream. A flag is returned to the function caller to signal the ! +! information availability. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! stream bwc_stream* - Structure used to assemble/ ! +! read a bwc bitstream. ! +! ! +! length unsigned int(64 bit) - Length of block to be read ! +! from stream. ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char sig- ! +! naling the availability of the ! +! requested information. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 06.02.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ + +// uchar +// can_read(bwc_stream const *const stream, +// uint64 const length) +// { +// /*-----------------------*\ +// ! DEFINE ASSERTIONS: ! +// \*-----------------------*/ +// assert(stream); +// assert(length); + +// return (stream->L + length > stream->Lmax) ? FAILURE : SUCCESS; +// } + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to properly deallocate a codestream in the field ! +! structure. If the field structure was set up to read from a codestream, all ! +! information stored in the global info and control structures, which are defined ! +! by the codestream, is reset. All pointers and paramters are properly ! +! reinitialize to NULL/0. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 30.04.2020 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +// void +// free_bwc(bwc_field *const field) +// { +// /*-----------------------*\ +// ! DEFINE INT VARIABLES: ! +// \*-----------------------*/ +// uint64 t; +// uint8 p; + +// /*-----------------------*\ +// ! DEFINE STRUCTS: ! +// \*-----------------------*/ +// bwc_cmd_opts_ll *param, *temp; + +// /*-----------------------*\ +// ! DEFINE ASSERTIONS: ! +// \*-----------------------*/ +// assert(field); + +// /*--------------------------------------------------------*\ +// ! If the codestream was set to read, deallocate the param- ! +// ! eter linked list, the array of the compressed and packed ! +// ! tile sizes and reset the global info and control struct. ! +// \*--------------------------------------------------------*/ +// if((field->codestream.flag & DATA_IN) != 0) +// { +// if(field->info.parameter != NULL) +// { +// param = field->info.parameter->root; + +// while(param != NULL) +// { +// temp = param; +// param = param -> next; +// free(temp); +// } +// } + +// free(field->control.packed_tile_size); + +// memset(&field->control, 0, sizeof(bwc_gl_ctrl)); +// memset(&field->info, 0, sizeof(bwc_gl_inf)); +// } + +// /*--------------------------------------------------------*\ +// ! Release all packed bitstreams holding the bwc codestream ! +// ! and close the file pointer to the compressed dataset. ! +// \*--------------------------------------------------------*/ +// release_packed_stream(&field->codestream.header.sgi); +// release_packed_stream(&field->codestream.header.sgc); +// release_packed_stream(&field->codestream.header.sgr); +// release_packed_stream(&field->codestream.header.aux); +// release_packed_stream(&field->codestream.header.com); +// release_packed_stream(&field->codestream.body); + +// fclose(field->codestream.fp); + +// /*--------------------------------------------------------*\ +// ! Reset all packed bitstreams, the header size and code- ! +// ! stream flag and function and file pointers ! +// \*--------------------------------------------------------*/ +// memset(&field->codestream.header.sgi, 0, sizeof(bwc_packed_stream)); +// memset(&field->codestream.header.sgc, 0, sizeof(bwc_packed_stream)); +// memset(&field->codestream.header.sgr, 0, sizeof(bwc_packed_stream)); +// memset(&field->codestream.header.aux, 0, sizeof(bwc_packed_stream)); +// memset(&field->codestream.header.com, 0, sizeof(bwc_packed_stream)); +// memset(&field->codestream.body, 0, sizeof(bwc_packed_stream)); + +// /*--------------------------------------------------------*\ +// ! If allocated, release the tile parameters as well as the ! +// ! pointer array used to store their memory addresses. ! +// \*--------------------------------------------------------*/ +// if((field->codestream.count > 0) && +// (field->codestream.body != NULL)) +// { +// for(t = 0; t < field->codestream.count; ++t) +// { +// field->memory.usage -= field->codestream.body[t].size; +// free(field->codestream.body[t].memory); +// } + +// free(field->codestream.body); + +// field->codestream.body = NULL; +// field->codestream.count = 0; +// field->codestream.idx = 0; +// } + +// field->codestream.header.size = 0; +// field->codestream.flag = DATA_CLR; + +// field->codestream.free = NULL; +// field->codestream.fp = NULL; +// } + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to read the header from a conforming bwc file and store ! +! its information in the bwc_field structure. ! +! In case of an error the function will free all allocated memory and return an ! +! error handle to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 28.04.2020 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +// uchar +// read_bwc_header(bwc_field *const field) +// { +// /*-----------------------*\ +// ! DEFINE INT VARIABLES: ! +// \*-----------------------*/ +// uint64 buff_long; +// uint64 i; + +// uint32 buff_int; +// uint32 L; + +// uint16 marker; + +// uint8 dim; +// uint8 samp; +// uint8 index, l; +// uint8 precision, p; + +// /*-----------------------*\ +// ! DEFINE CHAR VARIABLES: ! +// \*-----------------------*/ +// char *buff_char; +// uchar *memory; +// uchar status; + +// /*-----------------------*\ +// ! DEFINE STRUCTS: ! +// \*-----------------------*/ +// bwc_gl_inf *info; +// bwc_gl_ctrl *control; +// bwc_stream *stream; + +// /*-----------------------*\ +// ! DEFINE FILE POINTER: ! +// \*-----------------------*/ +// FILE *fp; + +// /*-----------------------*\ +// ! DEFINE ASSERTIONS: ! +// \*-----------------------*/ +// assert(field); + +// /*--------------------------------------------------------*\ +// ! Save the global info and control structure as well as ! +// ! the file pointer to temporary variables to make the code ! +// ! more readable. ! +// \*--------------------------------------------------------*/ +// info = &field->info; +// control = &field->control; + +// fp = field->codestream.fp; + +// /*--------------------------------------------------------*\ +// ! Initialize the codestream status marker and index. Loop ! +// ! through the codestream and extract the header info. ! +// \*--------------------------------------------------------*/ +// status = CODESTREAM_OK; +// index = 0; + +// while((status & CODESTREAM_ERROR) == 0) +// { +// /*--------------------------------------------------------*\ +// ! Extract the next marker from the file and verify that it ! +// ! has a valid value. If not, set the codestream error flag ! +// ! to stop the parser. ! +// \*--------------------------------------------------------*/ +// if(fread(&marker, sizeof(uint16), 1, fp) != 1) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// } + +// if(marker < 0xFF00) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// } + +// switch(marker) +// { +// /*--------------------------------------------------------*\ +// ! Check that the Start Of Codestream marker is the first ! +// ! marker to appear in the compressed dataset. If not, set ! +// ! the codestream error flag to stop the parser. ! +// \*--------------------------------------------------------*/ +// case SOC: +// { +// if(index != 0) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// } +// break; +// } + +// /*--------------------------------------------------------*\ +// ! Check that the Start of Global Information marker is the ! +// ! second marker to appear in the compressed dataset. If ! +// ! not, set the codestream error flag to stop the parser. ! +// \*--------------------------------------------------------*/ +// case SGI: +// { +// if(index != 1) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// /*--------------------------------------------------------*\ +// ! Acquire the global information block from the compressed ! +// ! codestream and set up the appropriate stream to extract ! +// ! its information. ! +// \*--------------------------------------------------------*/ +// if(fread(&L, sizeof(uint32), 1, fp) != 1) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// memory = calloc(sizeof(uchar), L - 4); +// if(memory == NULL) +// { +// // memory allocation error +// fprintf(stderr, MEMERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// if(fread(memory, sizeof(uchar), L - 4, fp) != (L - 4)) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// free(memory); +// break; +// } + +// stream = init_stream(memory, (L - 4), 'd'); +// if(stream == NULL) +// { +// // memory allocation error +// fprintf(stderr, MEMERROR); +// status |= CODESTREAM_ERROR; +// free(memory); +// break; +// } +// /*--------------------------------------------------------*\ +// ! Obtain the datset dimension, number of parameters, en- ! +// ! coder precision and file extension from the stream and ! +// ! store the values in the global information structure. ! +// \*--------------------------------------------------------*/ +// info->nX = get_symbol(stream, 8); +// info->nY = get_symbol(stream, 8); +// info->nZ = get_symbol(stream, 8); +// info->nTS = (uint16)get_symbol(stream, 2); +// info->numParams = (uint8)get_symbol(stream, 1); +// info->codec_prec = (uint8)get_symbol(stream, 1); + +// buff_char = (char*)get_chunck(stream, 10); +// if(buff_char == NULL) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// terminate_stream(stream, NULL); +// break; +// } + +// strncpy(info->file_ext, +// buff_char, +// sizeof(buff_char)/sizeof(*buff_char)); + +// free(buff_char); + +// /*--------------------------------------------------------*\ +// ! Loop over the parameters and... ! +// \*--------------------------------------------------------*/ +// for(p = 0; p < info->numParams && p < 255; ++p) +// { +// /*--------------------------------------------------------*\ +// ! obtain the parameter name, precision and sampling factor ! +// ! from the stream. Further, evaluate the spatial and tempo-! +// ! ral directions for which the sampling factor is active. ! +// \*--------------------------------------------------------*/ +// buff_char = (char*)get_chunck(stream, 24); +// if(buff_char == NULL) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// terminate_stream(stream, NULL); +// break; +// } + +// precision = (uint8)get_symbol(stream, 1); + +// samp = (uint8)get_symbol(stream, 1); +// dim = DIM_X; + +// buff_long = 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 = 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 = 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; + +// /*--------------------------------------------------------*\ +// ! Allocate and initialize the next linked list node used ! +// ! to store all the necessary parameter information. ! +// \*--------------------------------------------------------*/ +// if(info->parameter == NULL) +// { +// info->parameter = calloc(1, sizeof(bwc_cmd_opts_ll)); +// if(info->parameter == NULL) +// { +// // memory allocation error +// fprintf(stderr, MEMERROR); +// status |= CODESTREAM_ERROR; +// terminate_stream(stream, NULL); +// free(buff_char); +// break; +// } + +// info->parameter->root = info->parameter; +// } +// else +// { +// info->parameter->next = calloc(1, sizeof(bwc_cmd_opts_ll)); +// if(info->parameter->next == NULL) +// { +// // memory allocation error +// fprintf(stderr, MEMERROR); +// status |= CODESTREAM_ERROR; +// terminate_stream(stream, NULL); +// free(buff_char); +// break; +// } + +// 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 precision, samp- ! +// ! ling value, the dimension for which the sampling is ac- ! +// ! tive and the parameter size in the new node. ! +// \*--------------------------------------------------------*/ +// strcpy(info->parameter->name, buff_char); +// info->parameter->precision = precision; +// info->parameter->sample = samp; +// info->parameter->dim = dim; + +// info->parameter->size = (uint64)ceil((float)info->nX / (1 << ((dim & DIM_X) ? samp : 0))) * +// (uint64)ceil((float)info->nY / (1 << ((dim & DIM_Y) ? samp : 0))) * +// (uint64)ceil((float)info->nZ / (1 << ((dim & DIM_Z) ? samp : 0))) * +// (uint64)ceil((float)info->nTS / (1 << ((dim & DIM_TS) ? samp : 0))); + +// /*--------------------------------------------------------*\ +// ! Deallocate the character buffer. ! +// \*--------------------------------------------------------*/ +// free(buff_char); +// } + +// /*--------------------------------------------------------*\ +// ! Properly terminate and deallocate the global information ! +// ! stream, set the appropriate codestream status flag and ! +// ! return to the while loop. ! +// \*--------------------------------------------------------*/ +// if(terminate_stream(stream, NULL) == FAILURE) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// status |= CODESTREAM_SGI_READ; +// break; +// } + +// /*--------------------------------------------------------*\ +// ! Check that the Start of Global Control marker is the ! +// ! third marker to appear in the compressed dataset. If ! +// ! not, set the codestream error flag to stop the parser. ! +// \*--------------------------------------------------------*/ +// case SGC: +// { +// if(index != 2) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// bwc_kill_compression(field); +// status |= CODESTREAM_ERROR; +// break; +// } + +// /*--------------------------------------------------------*\ +// ! Acquire the Global Control block from the compressed ! +// ! codestream and setup the appropriate stream to extract ! +// ! its information. ! +// \*--------------------------------------------------------*/ +// if(fread(&L, sizeof(uint32), 1, fp) != 1) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// memory = calloc(sizeof(uchar), L - 4); +// if(memory == NULL) +// { +// // memory allocation error +// fprintf(stderr, MEMERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// if(fread(memory, sizeof(uchar), L - 4, fp) != (L - 4)) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// free(memory); +// break; +// } + +// stream = init_stream(memory, (L - 4), 'd'); +// if(stream == NULL) +// { +// // memory allocation error +// fprintf(stderr, MEMERROR); +// status |= CODESTREAM_ERROR; +// free(memory); +// break; +// } + +// /*--------------------------------------------------------*\ +// ! Obtain the CSsgc flag from the stream. Values that have ! +// ! been marked in this flag are red from the stream. Other- ! +// ! wise, the header information is skipped. ! +// \*--------------------------------------------------------*/ +// control->CSsgc = (uint16)get_symbol(stream, 2); + +// /*--------------------------------------------------------*\ +// ! If marked as user defined by the CSsgc flag, extract the ! +// ! tile sizes from the stream and evaluate the resulting ! +// ! number of tiles. ! +// \*--------------------------------------------------------*/ +// if(control->CSsgc & (0x01 << 0)) +// { +// control->tileSizeX = get_symbol(stream, 8); +// control->tileSizeY = get_symbol(stream, 8); +// control->tileSizeZ = get_symbol(stream, 8); +// control->tileSizeTS = get_symbol(stream, 2); + +// control->numTiles = (uint64)ceil(((float)info->nX / control->tileSizeX)) * +// (uint64)ceil(((float)info->nY / control->tileSizeY)) * +// (uint64)ceil(((float)info->nZ / control->tileSizeZ)) * +// (uint16)ceil(((float)info->nTS / control->tileSizeTS)); +// } +// else +// { +// FORWARD(stream, 26); +// } + +// /*--------------------------------------------------------*\ +// ! If marked as user defined by the CSsgc flag, extract the ! +// ! wavelet kernels from the stream. ! +// \*--------------------------------------------------------*/ +// if(control->CSsgc & (0x01 << 1)) +// { +// buff_long = get_symbol(stream, 1); + +// control->KernelX = (bwc_dwt_filter)(0x03 & (buff_long >> 6)); +// control->KernelY = (bwc_dwt_filter)(0x03 & (buff_long >> 4)); +// control->KernelZ = (bwc_dwt_filter)(0x03 & (buff_long >> 2)); +// control->KernelTS = (bwc_dwt_filter)(0x03 & buff_long); +// } +// else +// { +// FORWARD(stream, 1); +// } + +// /*--------------------------------------------------------*\ +// ! If marked as user defined by the CSsgc flag, extract the ! +// ! number of wavelet decompositions from the stream. ! +// \*--------------------------------------------------------*/ +// if(control->CSsgc & (0x01 << 2)) +// { +// buff_long = get_symbol(stream, 4); + +// control->numDecompX = (uint8)(0xFF & (buff_long >> 24)); +// control->numDecompY = (uint8)(0xFF & (buff_long >> 16)); +// control->numDecompZ = (uint8)(0xFF & (buff_long >> 8)); +// control->numDecompTS = (uint8)(0xFF & buff_long); + +// control->numDecomp = MAX(control->numDecompX, +// MAX(control->numDecompY, +// MAX(control->numDecompZ, control->numDecompTS))); +// } +// else +// { +// FORWARD(stream, 4); +// } + +// /*--------------------------------------------------------*\ +// ! If marked as user defined by the CSsgc flag, extract the ! +// ! precinct sizes from the stream. ! +// \*--------------------------------------------------------*/ +// if(control->CSsgc & (0x01 << 3)) +// { +// buff_long = get_symbol(stream, 2); + +// control->precSizeX = (uint8)(0x0F & (buff_long >> 8)); +// control->precSizeY = (uint8)(0x0F & (buff_long >> 12)); +// control->precSizeZ = (uint8)(0x0F & buff_long); +// control->precSizeTS = (uint8)(0x0F & (buff_long >> 4)); +// } +// else +// { +// FORWARD(stream, 2); +// } + + +// /*--------------------------------------------------------*\ +// ! If marked as user defined by the CSsgc flag, extract the ! +// ! codeblock sizes from the stream. ! +// \*--------------------------------------------------------*/ +// if(control->CSsgc & (0x01 << 4)) +// { +// buff_long = get_symbol(stream, 4); + +// control->cbX = (uint8)(0xFF & (buff_long >> 24)); +// control->cbY = (uint8)(0xFF & (buff_long >> 16)); +// control->cbZ = (uint8)(0xFF & (buff_long >> 8)); +// control->cbTS = (uint8)(0xFF & buff_long); +// } +// else +// { +// FORWARD(stream, 4); +// } + +// /*--------------------------------------------------------*\ +// ! If marked as user defined by the CSsgc flag, extract the ! +// ! progression order from the stream. ! +// \*--------------------------------------------------------*/ +// if(control->CSsgc & (0x01 << 5)) +// { +// control->progression = (bwc_prog_ord)get_symbol(stream, 1); +// } +// else +// { +// FORWARD(stream, 1); +// } + +// /*--------------------------------------------------------*\ +// ! If marked as user defined by the CSsgc flag, extract the ! +// ! resilience flag from the stream. ! +// \*--------------------------------------------------------*/ +// if(control->CSsgc & (0x01 << 6)) +// { +// control->resilience = (uchar)get_symbol(stream, 1); +// } +// else +// { +// FORWARD(stream, 1); +// } + +// /*--------------------------------------------------------*\ +// ! If marked as user defined by the CSsgc flag, extract the ! +// ! quantization style from the stream. ! +// \*--------------------------------------------------------*/ +// if(control->CSsgc & (0x01 << 7)) +// { +// control->quantization_style = (bwc_quant_st)get_symbol(stream, 1); +// } +// else +// { +// FORWARD(stream, 1); +// } + +// /*--------------------------------------------------------*\ +// ! If marked as user defined by the CSsgc flag, extract the ! +// ! Q number format range from the stream. ! +// \*--------------------------------------------------------*/ +// if(control->CSsgc & (0x01 << 8)) +// { +// control->Qm = (uint8)get_symbol(stream, 1); +// } +// else +// { +// FORWARD(stream, 1); +// } + +// /*--------------------------------------------------------*\ +// ! If marked as user defined by the CSsgc flag, extract the ! +// ! quantization step size mantissa and exponent from the ! +// ! stream. ! +// \*--------------------------------------------------------*/ +// if(control->CSsgc & (0x01 << 7)) +// { +// control->qt_exponent = (uint32)get_symbol(stream, 2); +// control->qt_mantissa = (uint32)get_symbol(stream, 2); +// } +// else +// { +// FORWARD(stream, 4); +// } + +// /*--------------------------------------------------------*\ +// ! Obtain the number of quality layers present in the code- ! +// ! stream and set up the bitrate array with the correspond- ! +// ! bitrates extracted from the stream. ! +// \*--------------------------------------------------------*/ +// control->numLayers = get_symbol(stream, 1); + +// for(l = 0; l < control->numLayers && l < 10; ++l) +// { +// buff_int = (uint32)get_symbol(stream, 4); +// control->bitrate[l] = *(float *)&buff_int; +// } + +// /*--------------------------------------------------------*\ +// ! Properly terminate and deallocate the global control ! +// ! stream, set the appropriate status flag and return to ! +// ! the while loop. ! +// \*--------------------------------------------------------*/ +// if(terminate_stream(stream, NULL) == FAILURE) +// { +// status |= CODESTREAM_ERROR; +// break; +// } + +// status |= CODESTREAM_SGC_READ; +// break; +// } + +// /*--------------------------------------------------------*\ +// ! Check that the Start of Global Register marker is the ! +// ! fourth marker to appear in the codestream. If not, set ! +// ! the error flag to stop the parser. ! +// \*--------------------------------------------------------*/ +// case SGR: +// { +// if(index != 3) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// bwc_kill_compression(field); +// status |= CODESTREAM_ERROR; +// break; +// } + +// /*--------------------------------------------------------*\ +// ! Acquire the Global Register block from the codestream ! +// ! store it in the global control structure. ! +// \*--------------------------------------------------------*/ +// if(fread(&L, sizeof(uint32), 1, fp) != 1) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// memory = calloc(sizeof(uchar), L - 4); +// if(memory == NULL) +// { +// // memory allocation error +// fprintf(stderr, MEMERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// if(fread(memory, sizeof(uchar), L - 4, fp) != (L - 4)) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// free(memory); +// break; +// } + +// control->packed_tile_size = (uint64*)memory; + +// /*--------------------------------------------------------*\ +// ! Set the appropriate codestream status flag and return to ! +// ! the while loop. ! +// \*--------------------------------------------------------*/ +// status |= CODESTREAM_SGR_READ; +// break; +// } + +// /*--------------------------------------------------------*\ +// ! Check that the Start of Aux. Information marker comes ! +// ! after the global information and control block. If not, ! +// ! set the codestream error flag to stop the parser. ! +// \*--------------------------------------------------------*/ +// case SAX: +// { +// if(index <= 3) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// bwc_kill_compression(field); +// status |= CODESTREAM_ERROR; +// break; +// } +// /*--------------------------------------------------------*\ +// ! Acquire the Auxiliary Information block from the code- ! +// ! stream and store it in the appropriate packed stream. ! +// \*--------------------------------------------------------*/ +// if(fread(&L, sizeof(uint32), 1, fp) != 1) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// memory = calloc(sizeof(uchar), L - 4); +// if(memory == NULL) +// { +// // memory allocation error +// fprintf(stderr, MEMERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// if(fread(memory, sizeof(uchar), L - 4, fp) != (L - 4)) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// field->codestream.header.aux.memory = memory; +// field->codestream.header.aux.size = L - 4; + +// /*--------------------------------------------------------*\ +// ! Set the appropriate codestream status flag and return to ! +// ! the while loop. ! +// \*--------------------------------------------------------*/ +// status |= CODESTREAM_SAX_READ; +// break; +// } + +// /*--------------------------------------------------------*\ +// ! Check that the Start of Com. Information marker comes ! +// ! after the global information and control block. If not, ! +// ! set the codestream error flag to stop the parser. ! +// \*--------------------------------------------------------*/ +// case COM: +// { +// if(index <= 3) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// bwc_kill_compression(field); +// status |= CODESTREAM_ERROR; +// break; +// } +// /*--------------------------------------------------------*\ +// ! Acquire the comment information block from the code- ! +// ! stream and store it in the appropriate packed stream. ! +// \*--------------------------------------------------------*/ +// if(fread(&L, sizeof(uint32), 1, fp) != 1) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// memory = calloc(sizeof(uchar), L - 4); +// if(memory == NULL) +// { +// // memory allocation error +// fprintf(stderr, MEMERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// if(fread(memory, sizeof(uchar), L - 4, fp) != (L - 4)) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// field->codestream.header.com.memory = memory; +// field->codestream.header.com.size = L - 4; + +// /*--------------------------------------------------------*\ +// ! Set the appropriate codestream status flag and return to ! +// ! the while loop. ! +// \*--------------------------------------------------------*/ +// status |= CODESTREAM_ERROR; +// break; +// } + +// /*--------------------------------------------------------*\ +// ! Check that Global Information, Control and Register mar- ! +// ! ker have all been read. If true, return to the function ! +// ! caller. Otherwise set the codestream error marker. ! +// \*--------------------------------------------------------*/ +// case EOH: +// { +// if(((status & CODESTREAM_SGI_READ) != 0) && +// ((status & CODESTREAM_SGC_READ) != 0) && +// ((status & CODESTREAM_SGR_READ) != 0) && +// (index > 3)) +// { +// return SUCCESS; +// } +// else +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// bwc_kill_compression(field); +// status |= CODESTREAM_ERROR; +// break; +// } +// } + +// /*--------------------------------------------------------*\ +// ! If the codestream marker is unknown, read the block size ! +// ! from file and forward the file pointer to the next mar- ! +// ! ker. ! +// \*--------------------------------------------------------*/ +// default: +// { +// if(fread(&L, sizeof(uint32), 1, fp) != 1) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// if(fseek(fp, (L - 4), SEEK_CUR) != 0) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// break; +// } + +// break; +// } +// } +// index++; +// } +// return FAILURE; +// } + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to write the header information stored in the bwc_field ! +! structure to a conforming bwc file. ! +! In case of an error the function will free all allocated memory and return an ! +! error handle to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 30.04.2020 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ uchar -assemble_main_header(bwc_field *const field) +write_bwc_header(bwc_field *const field) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 size; - uint16 Linf, Lctr; - uint8 p, l; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint32 buff_int; + uint16 buff_short; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_gl_ctrl *control; - bwc_gl_inf *info; - bwc_tile *tile; - bwc_parameter *parameter; - bwc_stream *stream; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(field); + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp; - /*--------------------------------------------------------*\ - ! 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; + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(field->codestream.fp != NULL); + assert(field->codestream.header.sgi.size > 0 && + field->codestream.header.sgc.size > 0 && + field->codestream.header.sgr.size > 0); - tile = &field->tile[0]; + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + fp = field->codestream.fp; - parameter = &tile->parameter[0]; - - Linf = 40 + info->nPar * 29; - Lctr = 50 + control->nLayers * 4; + /*--------------------------------------------------------*\ + ! Write the glb. Information, Control amd Register block, ! + ! including all necessary codestream markers, to file. ! + \*--------------------------------------------------------*/ + buff_short = SOC; - size = 6 + Linf + Lctr; + if(fwrite(&buff_short, sizeof(uint16), 1, fp) != 1) + { + // IO error + fprintf(stderr, WRTERROR); + return EXIT_FAILURE; + } - stream = bwc_init_stream(NULL, size, 'c'); - if(!stream) - { - // memory allocation error - return 1; - } + if(fwrite(field->codestream.header.sgi.memory, 1, + field->codestream.header.sgi.size, fp) != + field->codestream.header.sgi.size) + { + // IO error + fprintf(stderr, WRTERROR); + return EXIT_FAILURE; + } - 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); + if(fwrite(field->codestream.header.sgc.memory, 1, + field->codestream.header.sgc.size, fp) != + field->codestream.header.sgc.size) + { + // IO error + fprintf(stderr, WRTERROR); + return EXIT_FAILURE; + } - 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); - } + if(fwrite(field->codestream.header.sgr.memory, 1, + field->codestream.header.sgr.size, fp) != + field->codestream.header.sgr.size) + { + // IO error + fprintf(stderr, WRTERROR); + return EXIT_FAILURE; + } - bwc_emit_symbol(stream, SGC, 2); - bwc_emit_symbol(stream, Lctr, 2); + /*--------------------------------------------------------*\ + ! Check if an Auxiliary Information block is available. If ! + ! true, write the auxiliary information marker, its length ! + ! and the information block itself to the file. ! + \*--------------------------------------------------------*/ + if(field->codestream.header.aux.size > 0) + { + buff_short = SAX; + if(fwrite(&buff_short, sizeof(uint16), 1, fp) != 1) + { + // IO error + fprintf(stderr, WRTERROR); + return EXIT_FAILURE; + } - bwc_emit_symbol(stream, control->CSsgc, 2); + buff_int = field->codestream.header.aux.size + 4; + fwrite(&buff_int, sizeof(uint32), 1, fp); + { + // IO error + fprintf(stderr, WRTERROR); + return EXIT_FAILURE; + } - bwc_emit_symbol(stream, control->error_resilience, 1); + if(fwrite(field->codestream.header.aux.memory, 1, + field->codestream.header.aux.size, fp) != + field->codestream.header.aux.size) + { + // IO error + fprintf(stderr, WRTERROR); + return EXIT_FAILURE; + } + } - bwc_emit_symbol(stream, control->quantization_style, 1); - bwc_emit_symbol(stream, control->guard_bits, 1); + /*--------------------------------------------------------*\ + ! Check if a Comment block is available. If true, write ! + ! the comment marker, its length and the block itself to ! + ! the file. ! + \*--------------------------------------------------------*/ + if(field->codestream.header.com.size > 0) + { + buff_short = COM; + if(fwrite(&buff_short, sizeof(uint16), 1, fp) != 1) + { + // IO error + fprintf(stderr, WRTERROR); + return EXIT_FAILURE; + } - bwc_emit_symbol(stream, control->qt_exponent, 1); - bwc_emit_symbol(stream, control->qt_mantissa, 2); + buff_short = field->codestream.header.aux.size + 4; + fwrite(&buff_short, sizeof(uint32), 1, fp); + { + // IO error + fprintf(stderr, WRTERROR); + return EXIT_FAILURE; + } - bwc_emit_symbol(stream, control->progression, 1); - bwc_emit_symbol(stream, control->KernelX << 6 | control->KernelY << 4 | - control->KernelZ << 2 | control->KernelTS, 1); + if(fwrite(field->codestream.header.com.memory, 1, + field->codestream.header.com.size, fp) != + field->codestream.header.com.size) + { + // IO error + fprintf(stderr, WRTERROR); + return EXIT_FAILURE; + } + } - 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); + /*--------------------------------------------------------*\ + ! Write the end of header marker to the file and return to ! + ! the function caller. ! + \*--------------------------------------------------------*/ + buff_short = EOH; + if(fwrite(&buff_short, sizeof(uint16), 1, fp) != 1) + { + // IO error + fprintf(stderr, WRTERROR); + return EXIT_FAILURE; + } - 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; + return EXIT_SUCCESS; } -/*----------------------------------------------------------------------------------------------------------*\ -! 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) +/**********************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to properly deallocate a codestream in the field ! +! structure. If the field structure was set up to read from a codestream, all ! +! information stored in the global info and control structures, which are defined ! +! by the codestream, is reset. All pointers and paramters are properly ! +! reinitialize to NULL/0. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 30.04.2020 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +free_bwc(bwc_field *const field) { - /*-----------------------*\ - ! 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 INT VARIABLES: ! + \*-----------------------*/ + uint64 t; - /*-----------------------*\ - ! DEFINE CHAR VARIABLES: ! - \*-----------------------*/ - char* buffer_char; - char status; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_cmd_opts_ll *param, *temp; - /*-----------------------*\ - ! 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; + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); - status = CODESTREAM_OK; - index = 0; + /*--------------------------------------------------------*\ + ! If the codestream was set to read, deallocate the param- ! + ! eter linked list, the array of the compressed and packed ! + ! tile sizes and reset the global info and control struct. ! + \*--------------------------------------------------------*/ + if((field->codestream.flag & DATA_IN) != 0) + { + if(field->info.parameter != NULL) + { + param = field->info.parameter->root; - 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) + while(param != NULL) { - // Invalid Codestream - fprintf(stderr, CSERROR); - status |= CODESTREAM_ERROR; + temp = param; + param = param -> next; + free(temp); } - break; - } + } - case SGI: - { - if(index != 1 && !can_read(stream, 2)) - { - // Invalid Codestream - fprintf(stderr, CSERROR); - status |= CODESTREAM_ERROR; - break; - } + free(field->control.packed_tile_size); + field->memory.usage.codestream -= (field->control.numTiles * sizeof(uint64)); - Linf = (uint16)bwc_get_symbol(stream, 2); - if(!can_read(stream, Linf - 2)) - { - // Invalid Codestream - fprintf(stderr, CSERROR); - status |= CODESTREAM_ERROR; - break; - } + memset(&field->control, 0, sizeof(bwc_gl_ctrl)); + memset(&field->info, 0, sizeof(bwc_gl_inf)); + } - 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); + /*--------------------------------------------------------*\ + ! Release all packed bitstreams holding the bwc codestream ! + ! and close the file pointer to the compressed dataset. ! + \*--------------------------------------------------------*/ + field->memory.usage.codestream -= field->codestream.header.sgi.size; + release_packed_stream(&field->codestream.header.sgi); - buffer_char = (char*)bwc_get_chunck(stream, 10); - strncpy(info->f_ext, buffer_char, sizeof(buffer_char)/sizeof(*buffer_char)); - free(buffer_char); + field->memory.usage.codestream -= field->codestream.header.sgc.size; + release_packed_stream(&field->codestream.header.sgc); - for(p = 0; p < nPar; ++p) - { - buffer_char = (char*)bwc_get_chunck(stream, 24); + field->memory.usage.codestream -= field->codestream.header.sgr.size; + release_packed_stream(&field->codestream.header.sgr); - samp = (uint8)bwc_get_symbol(stream, 1); - dim = DIM_X; + field->memory.usage.codestream -= field->codestream.header.aux.size; + release_packed_stream(&field->codestream.header.aux); - 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; + field->memory.usage.codestream -= field->codestream.header.com.size; + release_packed_stream(&field->codestream.header.com); - 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; + if(field->codestream.fp != NULL) + fclose(field->codestream.fp); - 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; + /*--------------------------------------------------------*\ + ! Reset all packed bitstreams, the header size and code- ! + ! stream flag and function and file pointers ! + \*--------------------------------------------------------*/ + memset(&field->codestream.header.sgi, 0, sizeof(bwc_packed_stream)); + memset(&field->codestream.header.sgc, 0, sizeof(bwc_packed_stream)); + memset(&field->codestream.header.sgr, 0, sizeof(bwc_packed_stream)); + memset(&field->codestream.header.aux, 0, sizeof(bwc_packed_stream)); + memset(&field->codestream.header.com, 0, sizeof(bwc_packed_stream)); - precision = (uint8)bwc_get_symbol(stream, 1); + /*--------------------------------------------------------*\ + ! If allocated, release the tile parameters as well as the ! + ! pointer array used to store their memory addresses. ! + \*--------------------------------------------------------*/ + if(field->codestream.body != NULL) + { + for(t = 0; t < field->codestream.count; ++t) + { + field->memory.usage.codestream -= field->codestream.body[t].size; + free(field->codestream.body[t].memory); + } - bwc_add_param(data, buffer_char, samp, dim, precision); + free(field->codestream.body); - free(buffer_char); - } + field->codestream.body = NULL; + field->codestream.count = 0; + field->codestream.idx = 0; + } - field = bwc_initialize_field(data); - if(!field) - { - status |= CODESTREAM_ERROR; - break; - } + field->codestream.limit = + field->codestream.count = + field->codestream.idx = 0; - /*--------------------------------------------------------*\ - ! 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; + field->codestream.flag = DATA_CLR; + field->codestream.fp = 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to generate the global portion of the main codestream ! +! header. The global information and control blocks are assembled and stored in ! +! the "start of header" packed stream. ! +! In case of an error, all streams are terminated and an error handle is returned ! +! to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 02.06.2020 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ uchar -codestream_write_aux(bwc_packed_stream *const header, bwc_packed_stream *const aux) +initialize_main_header(bwc_field *const field) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint32 Laux; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint32 Linf, Lctr; + uint8 p, l; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_stream *stream; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(header); - assert(aux); + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; - stream = bwc_init_stream(header->memory, header->size, 'c'); - if(!stream) - { - // memory allocation error - return 1; - } + bwc_parameter *parameter; - Laux = aux->size + 4; + bwc_stream *stream; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); - stream->L = stream->Lmax; - stream->Lmax += Laux + 2; - stream->memory = realloc(stream->memory, stream->Lmax); - if(!stream->memory) - { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + info = &field->info; + control = &field->control; + + parameter = &field->setup.tile.parameter[0]; + + /*--------------------------------------------------------*\ + ! Initialize the global information stream with the appro- ! + ! priate size - including the necessary code markers. ! + \*--------------------------------------------------------*/ + Linf = 42 + info->numParams * 29; + + stream = init_stream(NULL, (2 + Linf), 'c'); + if(stream == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return 1; - } + return EXIT_FAILURE; + } - 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)) - { + /*--------------------------------------------------------*\ + ! Emit the Start of Global Information marker, alongside ! + ! the block length and all its parameters, to the stream. ! + \*--------------------------------------------------------*/ + emit_symbol(stream, SGI, 2); + emit_symbol(stream, Linf, 4); + emit_symbol(stream, info->nX, 8); + emit_symbol(stream, info->nY, 8); + emit_symbol(stream, info->nZ, 8); + emit_symbol(stream, info->nTS, 2); + emit_symbol(stream, info->numParams, 1); + emit_symbol(stream, info->codec_prec, 1); + emit_chunck(stream, (uchar*)info->file_ext, 10); + + for(p = 0; p < info->numParams; ++p) + { + emit_chunck(stream, (uchar*)parameter[p].info.name, 24); + emit_symbol(stream, parameter[p].info.precision, 1); + emit_symbol(stream, parameter[p].control.sampX, 1); + emit_symbol(stream, parameter[p].control.sampY, 1); + emit_symbol(stream, parameter[p].control.sampZ, 1); + emit_symbol(stream, parameter[p].control.sampTS, 1); + } + + /*--------------------------------------------------------*\ + ! Terminate the Global Information stream and flush its ! + ! content to the field header structure. ! + \*--------------------------------------------------------*/ + if(terminate_stream(stream, &field->codestream.header.sgi) == EXIT_FAILURE) + { // memory allocation error - return 1; - } + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } - return 0; + /*--------------------------------------------------------*\ + ! Initialize the global information stream with the appro- ! + ! priate size - including the necessary code markers. ! + \*--------------------------------------------------------*/ + Lctr = 52 + control->numLayers * 4; + + stream = init_stream(NULL, (2 + Lctr), 'c'); + if(stream == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Emit the Start of Global Control marker, alongside the ! + ! block length and all its parameters, to the stream. ! + \*--------------------------------------------------------*/ + emit_symbol(stream, SGC, 2); + emit_symbol(stream, Lctr, 4); + + emit_symbol(stream, control->CSsgc, 2); + + emit_symbol(stream, control->tileSizeX, 8); + emit_symbol(stream, control->tileSizeY, 8); + emit_symbol(stream, control->tileSizeZ, 8); + emit_symbol(stream, control->tileSizeTS, 2); + + emit_symbol(stream, control->KernelX << 6 | control->KernelY << 4 | + control->KernelZ << 2 | control->KernelTS, 1); + + emit_symbol(stream, control->numDecompX, 1); + emit_symbol(stream, control->numDecompY, 1); + emit_symbol(stream, control->numDecompZ, 1); + emit_symbol(stream, control->numDecompTS, 1); + + emit_symbol(stream, control->precSizeY << 4 | control->precSizeX, 1); + emit_symbol(stream, control->precSizeTS << 4 | control->precSizeZ, 1); + + emit_symbol(stream, control->cbX, 1); + emit_symbol(stream, control->cbY, 1); + emit_symbol(stream, control->cbZ, 1); + emit_symbol(stream, control->cbTS, 1); + + emit_symbol(stream, control->progression, 1); + + emit_symbol(stream, control->resilience, 1); + + emit_symbol(stream, control->quantization_style, 1); + + emit_symbol(stream, control->Qm, 1); + + emit_symbol(stream, control->qt_exponent, 2); + emit_symbol(stream, control->qt_mantissa, 2); + + emit_symbol(stream, control->numLayers, 1); + + for(l = 0; l < control->numLayers; ++l) + { + emit_symbol(stream, *(uint32 *)&control->bitrate[l], 4); + } + + /*--------------------------------------------------------*\ + ! Terminate the Global Control stream and flush its con- ! + ! tent to the field header structure. ! + \*--------------------------------------------------------*/ + if(terminate_stream(stream, &field->codestream.header.sgc) == EXIT_FAILURE) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Evaluate the main header size and check that it does not ! + ! exceed its maximum allowable value. If false, return an ! + ! error flag to the function caller. ! + \*--------------------------------------------------------*/ + control->main_header_size = field->codestream.header.sgi.size + + field->codestream.header.sgc.size + + field->codestream.header.aux.size + + field->codestream.header.com.size; + + if(control->main_header_size + 14 + (control->numTiles * 8) >= 0xFFFFFFFF) + { + // invalid header size + fprintf(stderr,"o==========================================================o\n"\ + "| ERROR: Invalid header size |\n"\ + "| |\n"\ + "| The header exceeds its size limit. Adjust |\n"\ + "| the optional header components (e.g. AUX) |\n"\ + "| to keep the overall number of bits under |\n"\ + "| the maximum size limit of 4294967295 bytes. |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + return EXIT_FAILURE; + } + else + { + field->memory.usage.codestream = control->main_header_size; + } + + /*--------------------------------------------------------*\ + ! Terminate the Global Information stream and flush its ! + ! content to the field header structure. ! + \*--------------------------------------------------------*/ + if(((field->codestream.flag & CS_STR) != 0) && + (field->codestream.fp != NULL)) + { + fseek(field->codestream.fp, control->main_header_size, SEEK_SET); + } + + /*--------------------------------------------------------*\ + ! Set the auxiliary information and comment block flag if ! + ! they have been defined by the user and return to the ! + ! function caller. ! + \*--------------------------------------------------------*/ + field->codestream.flag |= ((field->codestream.header.aux.size > 0) ? CS_AUX : 0); + field->codestream.flag |= ((field->codestream.header.com.size > 0) ? CS_COM : 0); + + + return EXIT_SUCCESS; } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to generate the global portion of the main codestream ! +! header. The global information and control blocks are assembled and stored in ! +! the "start of header" packed stream. ! +! In case of an error, all streams are terminated and an error handle is returned ! +! to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 02.06.2020 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ uchar -codestream_write_com(bwc_packed_stream *const header, bwc_packed_stream *const com) +finalize_main_header(bwc_field *const field) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint16 Lcom; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint32 Lreg; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_stream *stream; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(header); - assert(com); + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_stream *stream; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); - stream = bwc_init_stream(header->memory, header->size, 'c'); - if(!stream) - { - // memory allocation error - return 1; - } + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Initialize the Global Registry stream with the appropri- ! + ! ate size - including the necessary code markers. ! + \*--------------------------------------------------------*/ + Lreg = 4 + control->numTiles * 8; - Lcom = com->size + 2; - - stream->L = stream->Lmax; - stream->Lmax += Lcom + 2; - stream->memory = realloc(stream->memory, stream->Lmax); - if(!stream->memory) - { + stream = init_stream(NULL, (2 + Lreg), 'c'); + if(stream == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return 1; - } + return EXIT_FAILURE; + } - bwc_emit_symbol(stream, COM, 2); - bwc_emit_symbol(stream, Lcom, 2); - bwc_emit_chunck(stream, com->memory, com->size); + /*--------------------------------------------------------*\ + ! Emit the Start of Global Registry marker, alongside the ! + ! block length and all its parameters, to the stream. ! + \*--------------------------------------------------------*/ + emit_symbol(stream, SGR, 2); + emit_symbol(stream, Lreg, 4); + emit_chunck(stream, (uchar*)control->packed_tile_size, (Lreg - 4)); - 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) - { + /*--------------------------------------------------------*\ + ! Terminate the Global Registry stream and flush its con- ! + ! tent to the field header structure. ! + \*--------------------------------------------------------*/ + if(terminate_stream(stream, &field->codestream.header.sgr) == EXIT_FAILURE) + { // memory allocation error fprintf(stderr, MEMERROR); - return NULL; - } + return EXIT_FAILURE; + } - if(bwc_terminate_stream(stream, packed_stream)) - { - return NULL; - } - else - { - return packed_stream; - } + /*--------------------------------------------------------*\ + ! Terminate the Global Information stream and flush its ! + ! content to the field header structure. ! + \*--------------------------------------------------------*/ + if(((field->codestream.flag & CS_STR) != 0) && + (field->codestream.fp != NULL)) + { + fseek(field->codestream.fp, 0L, SEEK_SET); + + if(write_bwc_header(field) == EXIT_FAILURE) + { + return EXIT_FAILURE; + } + } + return EXIT_SUCCESS; } -/*----------------------------------------------------------------------------------------------------------*\ -! 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); +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to write the header information stored in the bwc_field ! +! structure to a conforming bwc file. ! +! In case of an error the function will free all allocated memory and return an ! +! error handle to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 13.06.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +// uchar +// assemble_tile(bwc_field *const field) +// { +// /*-----------------------*\ +// ! DEFINE INT VARIABLES: ! +// \*-----------------------*/ +// uint64 body_size; +// uint64 root; +// uint64 stream_size; +// uint64 tile_size; +// uint64 i, p; - /*--------------------------------------------------------*\ - ! Initialize a bitstream used to parse the packed code- ! - ! stream. ! - \*--------------------------------------------------------*/ - stream = bwc_init_stream(data->codestream.data->memory, - data->codestream.data->size, 'd'); +// uint32 t; +// uint32 Ltile; - /*--------------------------------------------------------*\ - ! 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; - } +// /*-----------------------*\ +// ! DEFINE CHAR VARIABLES: ! +// \*-----------------------*/ +// uchar *tmp; - /*--------------------------------------------------------*\ - ! Initialize the useLayer option to decompress the entire ! - ! codestream. ! - \*--------------------------------------------------------*/ - field->control.useLayer = field->control.nLayers - 1; +// /*-----------------------*\ +// ! DEFINE STRUCTS: ! +// \*-----------------------*/ +// bwc_gl_ctrl *control; +// bwc_gl_inf *info; - /*--------------------------------------------------------*\ - ! 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; - } +// bwc_tile *tile; - /*--------------------------------------------------------*\ - ! 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; - } +// bwc_packet *packet; - /*--------------------------------------------------------*\ - ! Free the bitstream used to parse the codestream and re- ! - ! turn the field structure to the function caller. ! - \*--------------------------------------------------------*/ - free(stream); +// bwc_stream *stream; +// bwc_packed_stream *tmp; - return field; -} \ No newline at end of file +// /*-----------------------*\ +// ! DEFINE ASSERTIONS: ! +// \*-----------------------*/ +// assert(field); + +// /*--------------------------------------------------------*\ +// ! Save frequently used variables/structures to temporary ! +// ! variables to make the code more readable. ! +// \*--------------------------------------------------------*/ +// control = &field->control; +// info = &field->info; + +// tile = &field->setup.tile; + +// /*--------------------------------------------------------*\ +// ! Evaluate the tile header length (Ltile), tile body size ! +// ! and overall tile size in the codestream. ! +// \*--------------------------------------------------------*/ +// Ltile = 14 + (info->numParams * 16); + +// body_size = control->packed_tile_size[tile->info->index]; +// tile_size = body_size + 6 + Ltile; + +// /*--------------------------------------------------------*\ +// ! Evaluate the stream size before (root) and after (stream ! +// ! _size) the current tile has been added - incl. the EOC ! +// ! marker following the last codestream tile segment. ! +// \*--------------------------------------------------------*/ +// root = field->codestream.body.size; + +// stream_size = root + tile_size; +// stream_size += (tile->info->index + 1 == control->numTiles) ? 2 : 0; + +// /*--------------------------------------------------------*\ +// ! Extend the packed body stream to account for the next ! +// ! tile, augment the memory usage and init. and forward the ! +// ! bitstream to concatenate the codestream segments. ! +// \*--------------------------------------------------------*/ +// tmp = realloc(field->codestream.body.memory, stream_size * sizeof(uchar)); +// if(tmp == NULL) +// { +// // memory allocation error +// fprintf(stderr, MEMERROR); +// return FAILURE; +// } + +// field->memory.usage += tile_size; + +// stream = init_stream(tmp, stream_size, 'c'); +// FORWARD(stream, root); + +// /*--------------------------------------------------------*\ +// ! Emit the Start of Tile marker, alongside the block ! +// ! length and all its parameters, to the stream. ! +// \*--------------------------------------------------------*/ +// emit_symbol(stream, SOT, 2); +// emit_symbol(stream, Ltile, 4); +// emit_symbol(stream, tile->info->index, 4); +// emit_symbol(stream, body_size, 8); + +// for(p = 0; p < info->numParams; ++p) +// { +// emit_symbol(stream, tile->parameter[p].info.max, 8); +// emit_symbol(stream, tile->parameter[p].info.min, 8); +// } + +// emit_symbol(stream, SOD, 2); + +// /*--------------------------------------------------------*\ +// ! Loop over all assembled codestream packets and ... ! +// \*--------------------------------------------------------*/ +// for(p = 0; p < tile->control.numPackets; ++p) +// { +// packet = tile->packet_sequence[p]; + +// /*--------------------------------------------------------*\ +// ! Emit the Start of Packet markers if the codestream is ! +// ! set for error resilience by the user. ! +// \*--------------------------------------------------------*/ +// if(control->resilience != 0) +// { +// emit_symbol(stream, SOP, 2); +// emit_symbol(stream, 4, 2); +// emit_symbol(stream, p % 0x100000000, 4); +// } + +// /*--------------------------------------------------------*\ +// ! If available, emit the packet header, incl. the End of ! +// ! Packet marker for an error resilience, to the codestream.! +// \*--------------------------------------------------------*/ +// if(packet->header.memory != NULL) +// { +// emit_chunck(stream, packet->header.memory, packet->header.size); + +// if(control->resilience != 0) +// { +// emit_symbol(stream, EPH, 2); +// } + +// release_packed_stream(&packet->header); +// } + +// /*--------------------------------------------------------*\ +// ! If available, emit the packet body to the codestream. ! +// \*--------------------------------------------------------*/ +// if(packet->body.memory != NULL) +// { +// emit_chunck(stream, packet->body.memory, packet->body.size); + +// release_packed_stream(&packet->body); +// } +// } + +// if(tile->info->index + 1 == control->numTiles) +// { +// emit_symbol(stream, EOC, 2); +// } + +// if(terminate_stream(stream, &field->codestream.body) == FAILURE) +// { +// return FAILURE; +// } + +// if(((field->codestream.flag & CS_STR) != 0) && +// (field->codestream.fp != NULL)) +// { +// if((field->memory.usage) >= field->memory.limit) +// { +// if(fwrite(field->codestream.body.memory, +// sizeof(uchar), +// field->codestream.body.size, +// field->codestream.fp) != field->codestream.body.size) +// { +// // invalid write +// fprintf(stderr, WRTERROR); +// return FAILURE; +// } + +// field->memory.usage -= field->codestream.body.size; + +// release_packed_stream(&field->codestream.body); +// } +// } +// } + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to write the header information stored in the bwc_field ! +! structure to a conforming bwc file. ! +! In case of an error the function will free all allocated memory and return an ! +! error handle to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 13.06.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +// parse_tile(bwc_field *const field) +// { +// /*-----------------------*\ +// ! DEFINE INT VARIABLES: ! +// \*-----------------------*/ +// uint16 Lunk; +// uint16 marker; + +// /*-----------------------*\ +// ! DEFINE CHAR VARIABLES: ! +// \*-----------------------*/ +// char status; + +// /*-----------------------*\ +// ! DEFINE ASSERTIONS: ! +// \*-----------------------*/ +// assert(field); + +// status = CODESTREAM_OK; + +// while((status & CODESTREAM_ERROR) == 0 && +// (can_read(stream, 2) == SUCCESS)) +// { +// marker = (uint16)get_symbol(stream, 2); +// if(marker < 0xFF00) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; +// } + +// switch(marker) +// { +// case SOT: +// { +// if(parse_tile(field, stream) == FAILURE) +// { +// status |= CODESTREAM_ERROR; +// } +// break; +// } + +// case EOC: +// { +// return SUCCESS; +// break; +// } + +// case SOC: +// case SGI: +// case SGC: +// case SAX: +// case COM: +// case EOH: +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// status |= CODESTREAM_ERROR; + +// break; +// } + +// default: +// { +// if(can_read(stream, 2) == FAILURE) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// bwc_kill_compression(field); +// status |= CODESTREAM_ERROR; +// break; +// } + +// Lunk = (uint16)get_symbol(stream, 2); +// if(can_read(stream, Lunk - 2) == FAILURE) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// bwc_kill_compression(field); +// status |= CODESTREAM_ERROR; +// break; +// } + +// stream->L += Lunk - 2; +// break; +// } +// } +// } +// return SUCCESS; + + +// /*-----------------------*\ +// ! 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) == FAILURE) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// return FAILURE; +// } + +// L = (uint16)get_symbol(stream, 2); + +// if(can_read(stream, L - 2) == FAILURE) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// return FAILURE; +// } + +// buf = (uint32)get_symbol(stream, 4); +// if(buf >= control->numTiles) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// return FAILURE; +// } + +// tile = &field->setup.tile; +// body_size = +// tile->control.body_size = (uint64)get_symbol(stream, 8); + +// if(SOD != (uint16)get_symbol(stream, 2)) +// { +// // Invalid Codestream +// fprintf(stderr, CSTERROR); +// return FAILURE; +// } +// else +// { +// /*--------------------------------------------------------*\ +// ! Sequence the packets according to the user specified op- ! +// ! tion. ! +// \*--------------------------------------------------------*/ +// if(sequence_packets(field, tile)) +// { +// return FAILURE; +// } + +// packet_index = 0; + +// while((body_size != 0) && +// (can_read(stream, body_size) == SUCCESS) && +// packet_index < tile->control.numPackets) +// { +// if(SOP == (uint16)get_symbol(stream, 2)) +// { +// if(can_read(stream, 6) == FAILURE) +// { +// //Invalid Codestream +// fprintf(stderr, CSTERROR); +// return FAILURE; +// } + +// if(4 != (uint16)get_symbol(stream, 2)) +// { +// //Invalid Codestream +// fprintf(stderr, CSTERROR); +// return FAILURE; +// } + +// buf = (uint32)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 FAILURE; +// } + +// forward_stream(stream, packet->size); + +// body_size -= packet->size; +// } +// } +// return SUCCESS; +// } + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function initializes an eas3 numerical dataset in the bwc_field structure ! +! with the corresponding utility structure as well as the suitable free function. ! +! If the file operation mode is set to read 'r', the function opens the specified ! +! file, parses its header and checks its validity. If verified, the header ! +! information, alongside the file pointer and appropriate read function, is ! +! stored in the bwc_field structure. ! +! If the file operation mode is set to read 'w', the function opens and writes ! +! the header information to the specified file. If successful, the file pointer ! +! and appropriate write function are stored in the bwc_field structure. ! +! In case of an error, the function will properly free the numerical dataset in ! +! the bwc_field structure and return an error flag to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! filename char* - Name of an eas3 file. ! +! ! +! mode char* - File operations mode. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 30.06.2020 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +// uchar +// open_bwc(bwc_field *const field, +// char const *const filename, +// char const *const mode) +// { +// /*-----------------------*\ +// ! DEFINE FILE POINTER: ! +// \*-----------------------*/ +// FILE *fp; + +// /*-----------------------*\ +// ! DEFINE ASSERTIONS: ! +// \*-----------------------*/ +// assert(field); +// assert(filename); + +// /*--------------------------------------------------------*\ +// ! Verify that the codestream field has not been set and i- ! +// ! nitialize it with the proper free function. ! +// \*--------------------------------------------------------*/ +// if(field->codestream.flag != CS_CLR) +// { +// // invalid read operation +// fprintf(stderr, "o##########################################################o\n"\ +// "| ERROR: Invalid IO |\n"\ +// "| |\n"\ +// "| Current bwc_field structure is already set |\n"\ +// "| to read from or write to a compressed data- |\n"\ +// "| set. |\n"\ +// "| |\n"\ +// "o##########################################################o\n"); +// return FAILURE; +// } + +// field->data.free = &free_bwc; + +// /*--------------------------------------------------------*\ +// ! Proceed according to the specified file operation marker.! +// \*--------------------------------------------------------*/ +// switch(*mode) +// { +// case 'r': +// { +// /*--------------------------------------------------------*\ +// ! Verify that the field structure is not already set to ! +// ! read from a numerical file. ! +// \*--------------------------------------------------------*/ +// if((field->data.flag & DATA_IN) != 0) +// { +// // invalid read operation +// fprintf(stderr, "o##########################################################o\n"\ +// "| ERROR: Invalid read |\n"\ +// "| |\n"\ +// "| The current bwc_field structure is already |\n"\ +// "| set to read from a numerical dataset. |\n"\ +// "| |\n"\ +// "o##########################################################o\n"); +// free_bwc(field); +// return FAILURE; +// } + +// /*--------------------------------------------------------*\ +// ! Open the specified file for reading and set the appropri-! +// ! ate codestream IO FLAG. ! +// \*--------------------------------------------------------*/ +// if((field->codestream.fp = 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); +// free_bwc(field); +// return FAILURE; +// } + +// field->codestream.flag |= (CS_IN & CS_STR); + +// /*--------------------------------------------------------*\ +// ! Read the bwc header and store its information and size ! +// ! in the field structure. ! +// \*--------------------------------------------------------*/ +// if(read_bwc_header(field)) +// { +// //error reading bwc header +// free_bwc(field); +// return FAILURE; +// } + +// field->codestream.header.size = ftell(fp); + +// break; +// } + +// case 'w': +// { +// /*--------------------------------------------------------*\ +// ! Verify that field structure is not already set to write ! +// ! to a numerical file. ! +// \*--------------------------------------------------------*/ +// if((field->data.flag & DATA_OUT) != 0) +// { +// // invalid read operation +// fprintf(stderr, "o##########################################################o\n"\ +// "| ERROR: Invalid write |\n"\ +// "| |\n"\ +// "| The current bwc_field structure is already |\n"\ +// "| set to write to a numerical dataset. |\n"\ +// "| |\n"\ +// "o##########################################################o\n"); +// free_bwc(field); +// return FAILURE; +// } + +// /*--------------------------------------------------------*\ +// ! Open the specified file for writing and set the appropri-! +// ! ate codestream IO FLAG. ! +// \*--------------------------------------------------------*/ +// if((field->codestream.fp = fp = fopen(filename, "wb")) == NULL) +// { +// // error opening file +// fprintf(stderr, "o##########################################################o\n"\ +// "| ERROR: Could not open or read %-25s|\n"\ +// "o##########################################################o\n", filename); +// free_bwc(field); +// return FAILURE; +// } + +// field->codestream.flag |= (CS_OUT & CS_STR); + +// break; +// } + +// default: +// { +// fprintf(stderr, "o##########################################################o\n"\ +// "| ERROR: Invalid file operation |\n"\ +// "o##########################################################o\n"); +// free_bwc(field); +// return FAILURE; +// } +// } + +// /*--------------------------------------------------------*\ +// ! Return to function caller. ! +// \*--------------------------------------------------------*/ +// return SUCCESS; +// } + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to write the header information stored in the bwc_field ! +! structure to a conforming bwc file. ! +! In case of an error the function will free all allocated memory and return an ! +! error handle to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 13.06.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +// uchar +// load_bwc(bwc_field *const field, +// char const *const filename) +// { +// /*-----------------------*\ +// ! DEFINE INT VARIABLES: ! +// \*-----------------------*/ +// uint64 size; +// uint32 root; + +// /*-----------------------*\ +// ! DEFINE CHAR VARIABLES: ! +// \*-----------------------*/ +// char *buffer; + +// /*-----------------------*\ +// ! DEFINE STRUCTS: ! +// \*-----------------------*/ +// bwc_cmd_opts_ll *param; + +// /*-----------------------*\ +// ! DEFINE ASSERTIONS: ! +// \*-----------------------*/ +// assert(field); +// assert(filename); + +// /*--------------------------------------------------------*\ +// ! Open the bwc file, parses its header and checks the file ! +// ! for its validity. ! +// \*--------------------------------------------------------*/ +// if(open_bwc(field, filename, 'r') == FAILURE) +// return FAILURE; + +// root = ftell(field->codestream.fp); +// fseek(field->codestream.fp, 0L, SEEK_END); +// size = ftell(field->codestream.fp) - root; + +// buffer = calloc(size, sizeof(uchar)); +// if(buffer == NULL) +// { +// // memory allocation error +// fprintf(stderr, MEMERROR); +// return FAILURE; +// } + +// if(fread(buffer, +// sizeof(uchar), +// size, +// field->codestream.fp)) +// { +// // Invalid read +// fprintf(stderr, RDERROR); +// free(buffer); +// return FAILURE; +// } + +// field->codestream.body.access = +// field->codestream.body.memory = buffer; +// field->codestream.body.size = size; + +// /*--------------------------------------------------------*\ +// ! Close the file pointer and return to the function caller.! +// \*--------------------------------------------------------*/ +// fclose(field->codestream.fp); + +// field->codestream.flag ^= CS_STR; +// field->codestream.fp = NULL; + +// return SUCCESS; +// } + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to write the header information stored in the bwc_field ! +! structure to a conforming bwc file. ! +! In case of an error the function will free all allocated memory and return an ! +! error handle to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 13.06.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +// uchar +// unload_bwc(bwc_field *const field, +// char const *const filename) +// { +// /*-----------------------*\ +// ! DEFINE ASSERTIONS: ! +// \*-----------------------*/ +// assert(field); +// assert(filename); + +// /*--------------------------------------------------------*\ +// ! Open and write the proper header to a bwc file. ! +// \*--------------------------------------------------------*/ +// if(open_bwc(field, filename, 'w') == FAILURE) +// return FAILURE; + +// if(write_bwc_header(field)) +// { +// //error writing bwc header +// return FAILURE; +// } + +// if(fwrite(field->codestream.body.memory, +// sizeof(uchar), +// field->codestream.body.size, +// field->codestream.fp) != field->codestream.body.size) +// { +// // Invalid write +// fprintf(stderr, MEMERROR); +// return FAILURE; +// } + +// /*--------------------------------------------------------*\ +// ! Close the file pointer and return the bwc_data structure ! +// ! to the function caller. ! +// \*--------------------------------------------------------*/ +// fclose(field->codestream.fp); + +// field->codestream.flag ^= CS_STR; +// field->codestream.fp = NULL; + +// return SUCCESS; +// } diff --git a/src/library/dwt.c b/src/library/dwt.c index de9a7c1..946d4c7 100755 --- a/src/library/dwt.c +++ b/src/library/dwt.c @@ -1,89 +1,52 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ - -/************************************************************************************************************\ -|| _ _ _ ____ _ _ _ ___ ____ || -|| | |\ | | | | | | \ |___ || -|| | | \| |___ |___ |__| |__/ |___ || -|| || -\************************************************************************************************************/ +/*====================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This file describes a set of functions that can be used to performe the forward/ || +|| inverse discrete wavelet transform on 1- to 4-dimensional IEEE 754 data-sets. For || +|| more information please refere to JPEG2000 by D. S. Taubman and M. W. Marcellin. || +|| || +|| ---------------------------------------------------------------------------------------------------------------- || +|| || +|| 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. || +|| || +\*====================================================================================================================*/ +/**********************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\**********************************************************************************************************************/ #include #include #include @@ -95,2587 +58,2602 @@ #include "types.h" #include "dwt.h" -/************************************************************************************************************\ -|| ____ _ _ ___ ____ ____ _ _ ____ _ _ _ ____ ____ _ ____ ___ _ ____ ____ || -|| |___ \/ | |___ |__/ |\ | |__| | | | |__| |__/ | |__| |__] | |___ [__ || -|| |___ _/\_ | |___ | \ | \| | | |___ \/ | | | \ | | | |__] |___ |___ ___] || -|| || -\************************************************************************************************************/ -double DWT_ENERGY_GAIN_LUT[3][2 * MAX_DECOMPOSITION_LEVELS + 2]; +/**********************************************************************************************************************\ +|| ____ _ _ ___ ____ ____ _ _ ____ _ _ _ ____ ____ _ ____ ___ _ ____ ____ || +|| |___ \/ | |___ |__/ |\ | |__| | | | |__| |__/ | |__| |__] | |___ [__ || +|| |___ _/\_ | |___ | \ | \| | | |___ \/ | | | \ | | | |__] |___ |___ ___] || +|| || +\**********************************************************************************************************************/ +double DWT_ENERGY_GAIN_LUT[3][2 * MAX_DECOMP_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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/**********************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function returns the rounded up maximum half length of a specified wavelet ! +! filter. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! dwt_filter bwc_dwt_filter - Wavelet kernel type. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uint8 - Rounded up maximum half-length ! +! of a wavelet filter. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 22.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 17.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static uint8 -get_filter_taps(bwc_dwt_filter dwt_filter) +get_filter_taps(bwc_dwt_filter const dwt_filter) { - /*--------------------------------------------------------*\ - ! Emit the rounded up maximum half-length of the specified ! - ! wavelet filter. ! - \*--------------------------------------------------------*/ - switch(dwt_filter) - { + switch(dwt_filter) + { case bwc_dwt_9_7: - { - return 4; - } + { + return 4; + } case bwc_dwt_5_3: - { - return 2; - } + { + return 2; + } case bwc_dwt_haar: - { - return 1; - } + { + return 1; + } default: - { - assert(0); - return 0; - } - } + { + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to copy the sample stripe from the strided data memory ! +! block to the working buffer for the forward one dimensional wavelet transform. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! data bwc_float* - Memory handle to the current ! +! samples ! +! ! +! working_buffer bwc_float* - Working buffer ! +! ! +! res0 unsigned int(64 bit) - Stripe starting point in the ! +! data memory block. ! +! ! +! res1 unsigned int(64 bit) - Stripe end point in the data ! +! memory block. ! +! ! +! increment unsigned int(64 bit) - Data increment for strided ! +! memory access. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 24.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 17.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -fill_forward_buffer(bwc_sample *const data, bwc_sample *const working_buffer, uint64 res0, uint64 res1, uint64 increment) +fill_forward_buffer(bwc_float *const data, + bwc_float *const working_buffer, + uint64 const res0, + uint64 const res1, + uint64 const increment) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 i, j; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i, j; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(data); - assert(working_buffer); + /*-----------------------*\ + ! 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) - { + /*--------------------------------------------------------*\ + ! Loop over the strided memory block and copy the samples ! + ! to the working buffer. ! + \*--------------------------------------------------------*/ + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to copy the sample stripe from the strided data memory ! +! block to the working buffer for the inverse one dimensional wavelet transform. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! data bwc_float* - Memory handle to the current ! +! samples ! +! ! +! working_buffer bwc_float* - Working buffer ! +! ! +! res0 unsigned int(64 bit) - Stripe starting point in the ! +! data memory block. ! +! ! +! res1 unsigned int(64 bit) - Stripe end point in the data ! +! memory block. ! +! ! +! increment unsigned int(64 bit) - Data increment for strided ! +! memory access. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 24.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 17.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -fill_inverse_buffer(bwc_sample *const data, bwc_sample *const working_buffer, uint64 res0, uint64 res1, uint64 increment) +fill_inverse_buffer(bwc_float *const data, + bwc_float *const working_buffer, + uint64 const res0, + uint64 const res1, + uint64 const increment) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int64 i, length, half_length; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i; + int64 length, half_length; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_sample *lowband, *highband; + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + bwc_float *highband; + bwc_float *lowband; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(data); - assert(working_buffer); + /*-----------------------*\ + ! 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; + /*--------------------------------------------------------*\ + ! 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; + /*--------------------------------------------------------*\ + ! 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; - } + /*--------------------------------------------------------*\ + ! 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] = *lowband; + 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; + /*--------------------------------------------------------*\ + ! In case of an odd resolution length, the half length is ! + ! decreased for an even or increased for an odd starting ! + ! point. ! + \*--------------------------------------------------------*/ + if((length % 2) != 0) + { + if((res0 % 2) == 0) + { + --half_length; + } + else + { + ++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; - } - } + /*--------------------------------------------------------*\ + ! 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] = *highband; + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to fill the boundary values of the working buffer with ! +! appropriate data samples 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_float* - Working buffer ! +! ! +! res0 unsigned int(64 bit) - Stripe starting point in the ! +! data memory block. ! +! ! +! res1 unsigned int(64 bit) - Stripe end point in the data ! +! memory block. ! +! ! +! nTaps unsigned int(64 bit) - Number of wavelet filter taps. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 17.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Function updated. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -whole_point_symmetric_extend(bwc_sample *const working_buffer, uint64 res0, uint64 res1, uint8 nTaps) +whole_point_symmetric_extend(bwc_float *const working_buffer, + uint64 const res0, + uint64 const res1, + uint8 const nTaps) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 i, length; - int64 j, min, max; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i, length; + int64 j, min, max; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(working_buffer); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(working_buffer); - length = res1 - res0; + length = res1 - res0; - if(nTaps < length) - { + 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 - { + { + 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; + { + 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]; + 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; + 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]; - } - } + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! 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_float* - Working buffer ! +! ! +! res0 unsigned int(64 bit) - Stripe starting point in the ! +! data memory block. ! +! ! +! res1 unsigned int(64 bit) - Stripe end point in the data ! +! memory block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 23.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -forward_9x7_CDF_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, uint64 res1) +forward_9x7_CDF_wavelet_transform(bwc_float *const working_buffer, + uint64 const res0, + uint64 const res1) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int64 i, length; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, length; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(working_buffer); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(working_buffer); - length = res1 - res0; + 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 predictor step on the odd samples. ! + \*--------------------------------------------------------*/ + for(i = -3; i < length + 3; i += 2) + { + working_buffer[i] += ALPHA * (working_buffer[i - 1] + working_buffer[i + 1]); + } - /*--------------------------------------------------------*\ - ! 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 first update step on the even samples. ! + \*--------------------------------------------------------*/ + for(i = -2; i < length + 2; i += 2) + { + working_buffer[i] += BETA * (working_buffer[i - 1] + working_buffer[i + 1]); + } - /*--------------------------------------------------------*\ - ! 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 predictor and scaling step on the odd ! + ! samples. ! + \*--------------------------------------------------------*/ + for(i = -1; i < length + 1; i += 2) + { + working_buffer[i] += GAMMA * (working_buffer[i - 1] + working_buffer[i + 1]); + working_buffer[i] = KAPPA_H * working_buffer[i]; + } - /*--------------------------------------------------------*\ - ! 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; - } + /*--------------------------------------------------------*\ + ! 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] += DELTA * (working_buffer[i - 1] + working_buffer[i + 1]); + working_buffer[i] = KAPPA_L * working_buffer[i]; + } } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! 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_float* - Working buffer ! +! ! +! res0 unsigned int(64 bit) - Stripe starting point in the ! +! data memory block. ! +! ! +! res1 unsigned int(64 bit) - Stripe end point in the data ! +! memory block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 23.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -inverse_9x7_CDF_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, uint64 res1) +inverse_9x7_CDF_wavelet_transform(bwc_float *const working_buffer, + uint64 const res0, + uint64 const res1) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int64 i, length; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, length; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(working_buffer); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(working_buffer); - length = res1 - res0; + 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 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] = KAPPA_H * working_buffer[i]; + working_buffer[i] -= DELTA * (working_buffer[i - 1] + working_buffer[i + 1]); + } - /*--------------------------------------------------------*\ - ! 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 second predictor and scaling step on the odd ! + ! samples. ! + \*--------------------------------------------------------*/ + for(i = -5; i < length + 3; i += 2) + { + working_buffer[i] = KAPPA_L * working_buffer[i]; + working_buffer[i] -= GAMMA * (working_buffer[i - 1] + working_buffer[i + 1]); + } - /*--------------------------------------------------------*\ - ! 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 update step on the even samples. ! + \*--------------------------------------------------------*/ + for(i = -4; i < length + 2; i += 2) + { + working_buffer[i] -= BETA * (working_buffer[i - 1] + working_buffer[i + 1]); + } - /*--------------------------------------------------------*\ - ! 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); - } + /*--------------------------------------------------------*\ + ! Perform the first predictor step on the odd samples. ! + \*--------------------------------------------------------*/ + for(i = -3; i < length + 1; i += 2) + { + working_buffer[i] -= ALPHA * (working_buffer[i - 1] + working_buffer[i + 1]); + } } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! 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_float* - Working buffer ! +! ! +! res0 unsigned int(64 bit) - Stripe starting point in the ! +! data memory block. ! +! ! +! res1 unsigned int(64 bit) - Stripe end point in the data ! +! memory block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 23.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -forward_5x3_LeGall_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, uint64 res1) +forward_5x3_LeGall_wavelet_transform(bwc_float *const working_buffer, + uint64 const res0, + uint64 const res1) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int64 i, length; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, length; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(working_buffer); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(working_buffer); - length = res1 - res0; + 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 predictor step on the odd samples. ! + \*--------------------------------------------------------*/ + for(i = -1; i < length + 1; i += 2) + { + working_buffer[i] -= (working_buffer[i - 1] + working_buffer[i + 1]) / 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; - } + /*--------------------------------------------------------*\ + ! Perform the update step on the even samples. ! + \*--------------------------------------------------------*/ + for(i = 0; i < length; i += 2) + { + working_buffer[i] += (working_buffer[i - 1] + working_buffer[i + 1] + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! 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_float* - Working buffer ! +! ! +! res0 unsigned int(64 bit) - Stripe starting point in the ! +! data memory block. ! +! ! +! res1 unsigned int(64 bit) - Stripe end point in the data ! +! memory block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 23.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -inverse_5x3_LeGall_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, uint64 res1) +inverse_5x3_LeGall_wavelet_transform(bwc_float *const working_buffer, + uint64 const res0, + uint64 const res1) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int64 i, length; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, length; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(working_buffer); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(working_buffer); - length = res1 - res0; + 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 update step on the even samples. ! + \*--------------------------------------------------------*/ + for(i = -2; i < length + 1; i += 2) + { + working_buffer[i] -= (working_buffer[i - 1] + working_buffer[i + 1] + 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; - } + /*--------------------------------------------------------*\ + ! Perform the predictor step on the odd samples. ! + \*--------------------------------------------------------*/ + for(i = -1; i < length; i += 2) + { + working_buffer[i] += (working_buffer[i - 1] + working_buffer[i + 1]) / 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! 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_float* - Working buffer ! +! ! +! res0 unsigned int(64 bit) - Stripe starting point in the ! +! data memory block. ! +! ! +! res1 unsigned int(64 bit) - Stripe end point in the data ! +! memory block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 23.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -forward_Haar_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, uint64 res1) +forward_Haar_wavelet_transform(bwc_float *const working_buffer, + uint64 const res0, + uint64 const res1) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int64 i, length; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, length; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(working_buffer); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(working_buffer); - length = res1 - res0; + 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 predictor step on the odd samples. ! + \*--------------------------------------------------------*/ + for(i = 1; i < length; i += 2) + { + working_buffer[i] -= working_buffer[i - 1]; + } - /*--------------------------------------------------------*\ - ! 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 update step on the even samples. ! + \*--------------------------------------------------------*/ + for(i = 0; i < length; i += 2) + { + working_buffer[i] += working_buffer[i + 1] / 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! 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_float* - Working buffer ! +! ! +! res0 unsigned int(64 bit) - Stripe starting point in the ! +! data memory block. ! +! ! +! res1 unsigned int(64 bit) - Stripe end point in the data ! +! memory block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 23.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -inverse_Haar_wavelet_transform(bwc_sample *const working_buffer, uint64 res0, uint64 res1) +inverse_Haar_wavelet_transform(bwc_float *const working_buffer, + uint64 const res0, + uint64 const res1) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int64 i, length; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, length; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(working_buffer); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(working_buffer); - length = res1 - res0; + 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 update step on the even samples. ! + \*--------------------------------------------------------*/ + for(i = 0; i < length; i += 2) + { + working_buffer[i] -= working_buffer[i + 1] / 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; - } + /*--------------------------------------------------------*\ + ! Perform the predictor step on the odd samples. ! + \*--------------------------------------------------------*/ + for(i = 1; i < length; i += 2) + { + working_buffer[i] += working_buffer[i - 1]; + } } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! 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 function loops through half_length-1 wavelet ! +! coefficients and handles the last (two) coefficient(s) separately. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! data bwc_float* - Memory handle to the current ! +! samples ! +! ! +! working_buffer bwc_float* - Working buffer ! +! ! +! res0 unsigned int(64 bit) - Stripe starting point in the ! +! data memory block. ! +! ! +! res1 unsigned int(64 bit) - Stripe end point in the data ! +! memory block. ! +! ! +! increment unsigned int(64 bit) - Data increment for strided ! +! memory access. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 23.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -buffer_flush_forward(bwc_sample *const data, bwc_sample *const working_buffer, uint64 res0, uint64 res1, uint64 increment) +buffer_flush_forward(bwc_float *const data, + bwc_float *const working_buffer, + uint64 const res0, + uint64 const res1, + uint64 const increment) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int64 i, length, half_length; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i; + int64 length, half_length; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_sample *lowband, *highband; + /*-----------------------*\ + ! DEFINE FLOAT: ! + \*-----------------------*/ + bwc_float *lowband; + bwc_float *highband; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(data); - assert(working_buffer); + /*-----------------------*\ + ! 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; + /*--------------------------------------------------------*\ + ! 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; + /*--------------------------------------------------------*\ + ! 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; - } + /*--------------------------------------------------------*\ + ! In case of an odd starting point copy the first highband ! + ! coefficient from the working buffer. ! + \*--------------------------------------------------------*/ + if(res0 % 2) + { + *highband = working_buffer[-1]; + 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; - } + /*--------------------------------------------------------*\ + ! 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 = working_buffer[i << 1]; + *highband = working_buffer[(i << 1) + 1]; + 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; - } + /*--------------------------------------------------------*\ + ! Copy the remaining high- and lowband coefficients accord-! + ! ing to the parity of the working buffer length. ! + \*--------------------------------------------------------*/ + if(res1 % 2) + { + *lowband = working_buffer[i << 1]; + } + else + { + *lowband = working_buffer[i << 1]; + *highband = working_buffer[(i << 1) + 1]; + } } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function copies the decompressed data samples for the current resolution ! +! level from the working buffer to the tile parameter memory. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! data bwc_float* - Memory handle to the current ! +! samples ! +! ! +! working_buffer bwc_float* - Working buffer ! +! ! +! res0 unsigned int(64 bit) - Stripe starting point in the ! +! data memory block. ! +! ! +! res1 unsigned int(64 bit) - Stripe end point in the data ! +! memory block. ! +! ! +! increment unsigned int(64 bit) - Data increment for strided ! +! memory access. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 25.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 23.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -buffer_flush_inverse(bwc_sample *const data, bwc_sample *const working_buffer, uint64 res0, uint64 res1, uint64 increment) +buffer_flush_inverse(bwc_float *const data, + bwc_float *const working_buffer, + uint64 const res0, + uint64 const res1, + uint64 const increment) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int64 i, j, length; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 i, j; + int64 length; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_sample *memory; + /*-----------------------*\ + ! DEFINE FLOAT: ! + \*-----------------------*/ + bwc_float *memory; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(data); - assert(working_buffer); + /*-----------------------*\ + ! 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; + /*--------------------------------------------------------*\ + ! Calculate the buffer length and associate the data point-! + ! er with the starting point of the tile parameter. ! + \*--------------------------------------------------------*/ + length = res1 - res0; + memory = data; - /*--------------------------------------------------------*\ - ! 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--; - } + /*--------------------------------------------------------*\ + ! In case of an odd starting point copy the first sample ! + ! to the tile parameter memory. ! + \*--------------------------------------------------------*/ + if(res0 % 2) + { + *memory = working_buffer[-1]; + 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; + /*--------------------------------------------------------*\ + ! Copy the decompressed data samples from the working buf- ! + ! fer to the strided tile parameter memory for the current ! + ! resolution level. ! + \*--------------------------------------------------------*/ + for(i = 0, j = 0; i < length; ++i) + { + memory[j] = working_buffer[i]; 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ + +/**********************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function calculates the energy gain factor Gb for the one dimensional ! +! CFD-(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 calculate 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 ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 21.03.2017 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 23.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ uchar initialize_gain_lut() { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int32 l,m; - int8 i,j,k; - int8 Length_FB, Length_Gb; + /*-----------------------*\ + ! 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 REAL VARIABLES: ! + \*-----------------------*/ + double *buff1, *buff2; + double *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 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; + /*-----------------------*\ + ! 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}}; + 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) - { + /*--------------------------------------------------------*\ + ! Allocate memory for the working buffers used to calcu- ! + ! late the energy gain factors. ! + \*--------------------------------------------------------*/ + buff1 = calloc(512, sizeof(double)); + buff2 = calloc(512, sizeof(double)); + if (buff1 == NULL || + buff2 == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); free(buff1); free(buff2); - return 1; - } + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! 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++) - { + /*--------------------------------------------------------*\ + ! 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_DECOMP_LEVELS + 1] = 1.0f; + DWT_ENERGY_GAIN_LUT[bwc_dwt_5_3][0] = DWT_ENERGY_GAIN_LUT[bwc_dwt_5_3][MAX_DECOMP_LEVELS + 1] = 1.0f; + DWT_ENERGY_GAIN_LUT[bwc_dwt_haar][0] = DWT_ENERGY_GAIN_LUT[bwc_dwt_haar][MAX_DECOMP_LEVELS + 1] = 1.0f; + + /*--------------------------------------------------------*\ + ! Loop through the symmetric wavelet filter banks and as- ! + ! semble the energy gain factor lookup tables. ! + \*--------------------------------------------------------*/ + 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. ! + ! Get the Lookup Table (LUT), Length and filter taps mem- ! + ! ory addresses and set the filter bank (FB) and working ! + ! buffer (Gb) length for the next wavelet filter bank. ! \*--------------------------------------------------------*/ 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]; - } + { + 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]; - } + { + 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 ! + ! Iterate over 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) + { + /*--------------------------------------------------------*\ + ! Initialize buffer 1 with the low-/high-pass filter taps ! + ! and calculate the energy gain factor for the first de- ! + ! comp. level by evaluating the square norm of buffer 1. ! + \*--------------------------------------------------------*/ + for(k = 0; k < Length_Gb + 1; ++k) { - 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]; - } + buff1[k] = buff1[2*Length_Gb-k] = filter_taps[k+5*j]; } - /*--------------------------------------------------------*\ - ! 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) + + for(k = 0; k < (2 * Length_Gb + 1); ++k) { - LUT[k] += buff1[l] * buff1[l]; + LUT[0] += buff1[k] * buff1[k]; } - } - /*--------------------------------------------------------*\ - ! 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]; - } + /*--------------------------------------------------------*\ + ! Iterate over the remaining decomposition levels and... ! + \*--------------------------------------------------------*/ + for(k = 1; k < MAX_DECOMP_LEVELS; ++k) + { + /*--------------------------------------------------------*\ + ! ... assemble the low-/high-pass synthesis sequence for ! + ! the current decomposition level i in 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]; + } + } + /*--------------------------------------------------------*\ + ! switch the memory addresses for buffer 1 and 2, set buf- ! + ! fer 2 to zero, reevaluate the length of buffer 1 and ... ! + \*--------------------------------------------------------*/ + 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 the current de- ! + ! comp. level by evaluating the square norm of 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_DECOMP_LEVELS + 1; + Length_Gb = Length[1]; + } /*--------------------------------------------------------*\ - ! Set work buffer 1 to 0. ! + ! Set 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) - { + /*--------------------------------------------------------*\ + ! 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. ! + ! Get the Lookup Table (LUT), Length and filter taps mem- ! + ! ory addresses and set the filter bank (FB) and working ! + ! buffer (Gb) length for the next wavelet filter bank. ! \*--------------------------------------------------------*/ - 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]; - } + 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 ! + ! Iterate over 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) + { + /*--------------------------------------------------------*\ + ! Initialize buffer 1 with the low-/high-pass filter taps ! + ! and calculate the energy gain factor for the first de- ! + ! comp. level by evaluating the square norm of buffer 1. ! + \*--------------------------------------------------------*/ + for(k = 0; k < Length_Gb; ++k) { - for(m = 0; m < Length_FB; m++) - { - buff2[2 * l + m] += buff1[l] * filter_taps[m]; - } + buff1[k] = filter_taps[k+5*j]; } - /*--------------------------------------------------------*\ - ! 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) + + for(k = 0; k < Length_Gb; ++k) { - LUT[k] += buff1[l] * buff1[l]; + LUT[0] += buff1[k] * buff1[k]; } - } - /*--------------------------------------------------------*\ - ! 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]; - } + /*--------------------------------------------------------*\ + ! Iterate over the remaining decomposition levels and... ! + \*--------------------------------------------------------*/ + for(k = 1; k < MAX_DECOMP_LEVELS; ++k) + { + /*--------------------------------------------------------*\ + ! ... assemble the low-/high-pass synthesis sequence for ! + ! the current decomposition level i in 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]; + } + } + /*--------------------------------------------------------*\ + ! switch the memory addresses for buffer 1 and 2, set buf- ! + ! fer 2 to zero, reevaluate the length of buffer 1 and ... ! + \*--------------------------------------------------------*/ + temp = buff1; + buff1 = buff2; + buff2 = temp; + + memset(buff2, 0, 512 * sizeof(double)); + Length_Gb = Length_Gb * Length_FB; + + /*--------------------------------------------------------*\ + ! ... calculate the energy gain factor for the current de- ! + ! comp. level by evaluating the square norm of buffer 1. ! + \*--------------------------------------------------------*/ + for(l = 0; l < Length_Gb; ++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_DECOMP_LEVELS + 1; + Length_Gb = Length[1]; + } /*--------------------------------------------------------*\ - ! Set work buffer 1 to 0. ! + ! Set 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; + } + /*--------------------------------------------------------*\ + ! Free buffer 1 and 2 and return to the function caller. ! + \*--------------------------------------------------------*/ + free(buff1); + free(buff2); + return EXIT_SUCCESS; } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function evaluates the energy gain factor according to the the specified ! +! decomposition level. For decomposition levels larger than MAX_DECOMP_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* - Codec control structure. ! +! ! +! highband unsigned char - Highband-Type represented by the ! +! current subband. ! +! ! +! level unsigned int(16 bit) - Decomposition level. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! bwc_float - Energy gain factor for the ! +! requested subband. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 13.04.2017 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 23.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ bwc_float -get_dwt_energy_gain(bwc_field *const field, uchar highband_flag, uint16 level) +get_dwt_energy_gain(bwc_field *const field, + uchar const highband, + uint16 const level) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int8 level_X, level_Y, level_Z; - int8 level_TS; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int8 level_X, level_Y, level_Z; + int8 level_TS; - /*-----------------------*\ - ! DEFINE FLOAT VARIABLES: ! - \*-----------------------*/ - double Gb = 1.0f; + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + double Gb = 1.0f; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_gl_ctrl *control; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(field); - assert(level <= field->control.nDecomp + 1); - assert(highband_flag <= DIM_ALL); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(level <= field->control.numDecomp + 1); + assert(highband <= DIM_ALL); - /*--------------------------------------------------------*\ - ! Save the global control structure to a temporary varia- ! - ! ble to make the code more readable. ! - \*--------------------------------------------------------*/ - control = &field->control; + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables 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; + /*--------------------------------------------------------*\ + ! Evaluate the number of decompositions in all spatial and ! + ! temporal directions that have been applied to the sub- ! + ! band defined by user specified level and highband. ! + \*--------------------------------------------------------*/ + level_X = (level > control->numDecompX) ? control->numDecompX : level; + level_Y = (level > control->numDecompY) ? control->numDecompY : level; + level_Z = (level > control->numDecompZ) ? control->numDecompZ : level; + level_TS = (level > control->numDecompTS) ? control->numDecompTS : 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--; - } + /*--------------------------------------------------------*\ + ! Evaluate the energy gain caused by applying the wavelet ! + ! filter to the first spatial axis. Multiply the gain by 2 ! + ! for decomp. levels larger than MAX_DECOMP_LEVELS. ! + \*--------------------------------------------------------*/ + if(level_X != 0) + { + while(level_X > MAX_DECOMP_LEVELS) + { + Gb *= 2.0f; + level_X--; + } - Gb *= DWT_ENERGY_GAIN_LUT[control->KernelX][level_X + ((highband_flag & DIM_X) * (MAX_DECOMPOSITION_LEVELS + 1))]; - } + Gb *= DWT_ENERGY_GAIN_LUT[control->KernelX][level_X + ((highband & DIM_X) * (MAX_DECOMP_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--; - } + /*--------------------------------------------------------*\ + ! Evaluate the energy gain caused by applying the wavelet ! + ! filter to the second spatial axis. Multiply the gain by ! + ! 2 for dcmp. levels larger than MAX_DECOMP_LEVELS. ! + \*--------------------------------------------------------*/ + if(level_Y != 0) + { + while(level_Y > MAX_DECOMP_LEVELS) + { + Gb *= 2.0f; + level_Y--; + } - Gb *= DWT_ENERGY_GAIN_LUT[control->KernelY][level_Y + (((highband_flag & DIM_Y) >> 1) * (MAX_DECOMPOSITION_LEVELS + 1))]; - } + Gb *= DWT_ENERGY_GAIN_LUT[control->KernelY][level_Y + (((highband & DIM_Y) >> 1) * (MAX_DECOMP_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--; - } + /*--------------------------------------------------------*\ + ! Evaluate the energy gain caused by applying the wavelet ! + ! filter to the first spatial axis. Multiply the gain by 2 ! + ! for decomp. levels larger than MAX_DECOMP_LEVELS. ! + \*--------------------------------------------------------*/ + if(level_Z != 0) + { + while(level_Z > MAX_DECOMP_LEVELS) + { + Gb *= 2.0f; + level_Z--; + } - Gb *= DWT_ENERGY_GAIN_LUT[control->KernelZ][level_Z + (((highband_flag & DIM_Z) >> 2) * (MAX_DECOMPOSITION_LEVELS + 1))]; - } + Gb *= DWT_ENERGY_GAIN_LUT[control->KernelZ][level_Z + (((highband & DIM_Z) >> 2) * (MAX_DECOMP_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--; - } + /*--------------------------------------------------------*\ + ! Evaluate the energy gain caused by applying the wavelet ! + ! to the temporal axis. Multiply the gain by 2 for decom- ! + ! position levels larger than MAX_DECOMP_LEVELS. ! + \*--------------------------------------------------------*/ + if(level_TS != 0) + { + while(level_TS > MAX_DECOMP_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; + Gb *= DWT_ENERGY_GAIN_LUT[control->KernelTS][level_TS + (((highband & DIM_TS) >> 3) * (MAX_DECOMP_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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function performs the forward discrete wavelet transform on a tile ! +! parameter. After loading the samples 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 transformed using ! +! the wavelet kernel selected for the particular 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 ! +! the user specified number of decomposition levels. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! parameter bwc_parameter* - Parameter control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 13.04.2017 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 23.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ uchar -forward_discrete_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter) +forward_wavelet_transform(bwc_field *const field, + uint16 const parID) { - /*-----------------------*\ - ! 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 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; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_gl_ctrl *control; - bwc_param_inf *param_info; - bwc_sample *data, *working_buffer; - bwc_sample **memory; + uint32 buff_size; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(field); - assert(parameter); + int16 i; + uint16 incr_TS; + uint16 rTS0; + uint16 rTS1; + uint16 dt; + uint16 t; - /*-----------------------*\ - ! 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}; + uint8 id; + uint8 filter_tapsX, filter_tapsY; + uint8 filter_tapsZ, filter_tapsTS; + uint8 level; + uint8 numThreads; - void (*boundary_extension[3])(bwc_sample *, uint64, uint64, uint8) = {whole_point_symmetric_extend, - whole_point_symmetric_extend, - NULL}; + /*-----------------------*\ + ! DEFINE FLOAT: ! + \*-----------------------*/ + bwc_float *data, *working_buffer; + bwc_float **memory; - /*--------------------------------------------------------*\ - ! Save the global control and parameter info structure to ! - ! temporary variables to make the code more readable. ! - \*--------------------------------------------------------*/ - control = &field->control; - param_info = ¶meter->info; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; - /*--------------------------------------------------------*\ - ! 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; + bwc_param_inf *param_info; + bwc_parameter *parameter; - /*--------------------------------------------------------*\ - ! 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; + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); - /*--------------------------------------------------------*\ - ! 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; + /*-----------------------*\ + ! DEFINE FUNCTION PTR: ! + \*-----------------------*/ + void (*forward_wavelet_transform[3])(bwc_float*, uint64, uint64) = {forward_9x7_CDF_wavelet_transform, + forward_5x3_LeGall_wavelet_transform, + forward_Haar_wavelet_transform}; - /*--------------------------------------------------------*\ - ! 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 + void (*boundary_extension[3])(bwc_float*, uint64, uint64, uint8) = {whole_point_symmetric_extend, + whole_point_symmetric_extend, + NULL}; - buff_size = MAX(MAX(width, height), MAX(depth, dt)) + 2 * - MAX(MAX(filter_tapsX, filter_tapsY), - MAX(filter_tapsZ, filter_tapsTS)); + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; - /*--------------------------------------------------------*\ - ! 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) - { + parameter = &field->setup.tile.parameter[parID]; + param_info = ¶meter->info; + + /*--------------------------------------------------------*\ + ! Calculate the width, height, depth and dt of the current ! + ! tile parameter, as well as the increments used to fill ! + ! the working buffer. ! + \*--------------------------------------------------------*/ + 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; + + 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. Increase by two to account for a pos- ! + ! sible 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 buffer size for the current tile parameter ! + ! according to the specified number of OpenMP threads. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + numThreads = control->numThreads; + #else + numThreads = 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 working buffer array for the specified num- ! + ! ber of OpenMP threads. In case of a serial run only one ! + ! memory block is allocated. ! + \*--------------------------------------------------------*/ + memory = calloc(numThreads, sizeof(bwc_float*)); + if(memory == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return 1; - } + return EXIT_FAILURE; + } - 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) + for(i = 0; i < numThreads; ++i) + { + memory[i] = calloc(buff_size, sizeof(bwc_float)); + if(memory[i] == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + for(i--; i > 0; --i) { - free(memory[i]); + free(memory[i]); } - free(memory); - return 1; - } - } + free(memory); + return EXIT_FAILURE; + } + } - /*--------------------------------------------------------*\ - ! 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 - { + /*--------------------------------------------------------*\ + ! 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(); + id = omp_get_thread_num(); #else - id = 0; + 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; + for(level = 0; level < control->numDecomp; ++level) + { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + rX0 = (uint64)parameter->resolution[control->numDecomp - level].info.X0; + rX1 = (uint64)parameter->resolution[control->numDecomp - level].info.X1; + rY0 = (uint64)parameter->resolution[control->numDecomp - level].info.Y0; + rY1 = (uint64)parameter->resolution[control->numDecomp - level].info.Y1; + rZ0 = (uint64)parameter->resolution[control->numDecomp - level].info.Z0; + rZ1 = (uint64)parameter->resolution[control->numDecomp - level].info.Z1; + rTS0 = (uint16)parameter->resolution[control->numDecomp - level].info.TS0; + rTS1 = (uint16)parameter->resolution[control->numDecomp - 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) + if((level < control->numDecompX) && ((rX1 - rX0) > 1)) { - ++working_buffer; + /*--------------------------------------------------------*\ + ! Associate the working buffer with the appropriate start- ! + ! ing point in the memory block. Adjust the buffer point- ! + ! er in case of an odd starting point in the curr. column. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsX]; + + if(rX0 % 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(y = 0; y < (rY1 - rY0); ++y) + { + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next row. ! + \*--------------------------------------------------------*/ + data = parameter->data + y * incr_Y + z * incr_Z + t * incr_TS; + + /*--------------------------------------------------------*\ + ! In case the current row only encompasses 1 value the it- ! + ! eration will be skipped. For an odd starting pont, the ! + ! sample will be multiplied by two to manage filter gain. ! + \*--------------------------------------------------------*/ + if((rX1 - rX0) == 1) + { + if(rX0 & 2) + { + data[0] *= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the next tile parameter row.! + \*--------------------------------------------------------*/ + 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 row.! + \*--------------------------------------------------------*/ + 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); + } + } + } } - /*--------------------------------------------------------*\ - ! 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) + if((level < control->numDecompY) && ((rY1 - rY0) > 1)) { - for(z = 0; z < (rZ1 - rZ0); ++z) - { + /*--------------------------------------------------------*\ + ! Associate the working buffer with the appropriate start- ! + ! ing point in the memory block. Adjust the buffer point- ! + ! er in case of an odd starting point in the curr. column. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsY]; + + if(rY0 % 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(x = 0; x < (rX1 - rX0); ++x) + { + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next column. ! + \*--------------------------------------------------------*/ + data = parameter->data + x * incr_X + z * incr_Z + t * incr_TS; + + /*--------------------------------------------------------*\ + ! In case the current column only encompasses 1 value the ! + ! iteration will be skipped. For an odd starting pont, the ! + ! sample will be multiplied by two to manage filter gain. ! + \*--------------------------------------------------------*/ + if((rY1 - rY0) == 1) + { + if(rY0 & 2) + { + data[0] *= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the next tile parameter col-! + ! umn. ! + \*--------------------------------------------------------*/ + 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 ! + ! column. ! + \*--------------------------------------------------------*/ + 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->numDecompZ) && ((rZ1 - rZ0) > 1)) + { + /*--------------------------------------------------------*\ + ! Associate the working buffer with the appropriate start- ! + ! ing point in the memory block. Adjust the buffer point- ! + ! er in case of an odd starting point in the curr. slice. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsZ]; + + if(rZ0 % 2) + { + working_buffer++; + } + + /*--------------------------------------------------------*\ + ! Walk trough all the temporal slices, columns and rows. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp for collapse(3) + #endif + for(t = 0; t < (rTS1 - rTS0); ++t) + { 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) + { + for(x = 0; x < (rX1 - rX0); ++x) { - data[0].f *= 2; + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next slice. ! + \*--------------------------------------------------------*/ + data = parameter->data + x * incr_X + y * incr_Y + t * incr_TS; + + /*--------------------------------------------------------*\ + ! In case the current slice only encompasses 1 value the ! + ! iteration will be skipped. For an odd starting pont, the ! + ! sample will be multiplied by two to manage filter gain. ! + \*--------------------------------------------------------*/ + if((rZ1 - rZ0) == 1) + { + if(rZ0 & 2) + { + data[0] *= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the next tile parameter ! + ! 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 ! + ! 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); } - 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) + if((level < control->numDecompTS) && ((rTS1 - rTS0) > 1)) { - 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; + /*--------------------------------------------------------*\ + ! Associate the working buffer with the appropriate start- ! + ! ing point in the memory block. Adjust the buffer point- ! + ! er in case of an odd starting point in the curr. slice. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsTS]; - /*--------------------------------------------------------*\ - ! 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) + if(rTS0 % 2) + { + working_buffer++; + } + + /*--------------------------------------------------------*\ + ! Walk trough all the spatial slices, columns and rows. ! + \*--------------------------------------------------------*/ + #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) { - data[0].f *= 2; + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next temporal slice. ! + \*--------------------------------------------------------*/ + data = parameter->data + x * incr_X + y * incr_Y + z * incr_Z; + + /*--------------------------------------------------------*\ + ! In case the current slice only encompasses 1 value the ! + ! iteration will be skipped. For an odd starting pont, the ! + ! sample will be multiplied by two to manage filter gain. ! + \*--------------------------------------------------------*/ + if((rTS1 - rTS0) == 1) + { + if(rTS0 & 2) + { + data[0] *= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the next tile parameter ! + ! temporal 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); } - 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) - { + /*--------------------------------------------------------*\ + ! Deallocate the buffer array and memory blocks. ! + \*--------------------------------------------------------*/ + for(i = 0; i < numThreads; ++i) + { free(memory[i]); - } - free(memory); + } + free(memory); - return 0; + return EXIT_SUCCESS; } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function performs the inverse discrete wavelet transform on a tile ! +! parameter. 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 ! +! transformed using the wavelet 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* - Codec control structure. ! +! ! +! parameter bwc_parameter* - Parameter control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 13.04.2017 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 24.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ uchar -inverse_discrete_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter) +inverse_wavelet_transform(bwc_field *const field, + uint16 const parID) { - /*-----------------------*\ - ! 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 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; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_gl_ctrl *control; - bwc_param_inf *param_info; - bwc_sample *data, *working_buffer; - bwc_sample **memory; + uint32 buff_size; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(field); - assert(parameter); + int16 i; + uint16 incr_TS; + uint16 rTS0; + uint16 rTS1; + uint16 dt; + uint16 t; - /*-----------------------*\ - ! 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}; + uint8 id; + uint8 filter_tapsX, filter_tapsY; + uint8 filter_tapsZ, filter_tapsTS; + uint8 level; + uint8 numThreads; - void (*boundary_extension[3])(bwc_sample *, uint64, uint64, uint8) = {whole_point_symmetric_extend, - whole_point_symmetric_extend, - NULL}; + /*-----------------------*\ + ! DEFINE FLOAT: ! + \*-----------------------*/ + bwc_float *data, *working_buffer; + bwc_float **memory; - /*--------------------------------------------------------*\ - ! Save the global control and parameter info structure to ! - ! temporary variables to make the code more readable. ! - \*--------------------------------------------------------*/ - control = &field->control; - param_info = ¶meter->info; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; - /*--------------------------------------------------------*\ - ! 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; + bwc_parameter *parameter; + bwc_param_inf *param_info; - /*--------------------------------------------------------*\ - ! 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; + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); - /*--------------------------------------------------------*\ - ! 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; + /*-----------------------*\ + ! DEFINE FUNCTION PTR: ! + \*-----------------------*/ + void (*inverse_wavelet_transform[3])(bwc_float*, uint64, uint64) = {inverse_9x7_CDF_wavelet_transform, + inverse_5x3_LeGall_wavelet_transform, + inverse_Haar_wavelet_transform}; - /*--------------------------------------------------------*\ - ! 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 + void (*boundary_extension[3])(bwc_float*, uint64, uint64, uint8) = {whole_point_symmetric_extend, + whole_point_symmetric_extend, + NULL}; - buff_size = MAX(MAX(width, height), MAX(depth, dt)) + 2 * - MAX(MAX(filter_tapsX, filter_tapsY), - MAX(filter_tapsZ, filter_tapsTS)); + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; - /*--------------------------------------------------------*\ - ! 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) - { + parameter = &field->setup.tile.parameter[parID]; + param_info = ¶meter->info; + + /*--------------------------------------------------------*\ + ! Calculate the width, height, depth and dt of the current ! + ! tile parameter, as well as the increments used to fill ! + ! the working buffer. ! + \*--------------------------------------------------------*/ + 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; + + 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. Increase by two to account for a pos- ! + ! sible 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 buffer size for the current tile parameter ! + ! according to the specified number of OpenMP threads. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + numThreads = control->numThreads; + #else + numThreads = 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 working buffer array for the specified num- ! + ! ber of OpenMP threads. In case of a serial run only one ! + ! memory block is allocated. ! + \*--------------------------------------------------------*/ + memory = calloc(numThreads, sizeof(bwc_float*)); + if(memory == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return 1; - } + return EXIT_FAILURE; + } - 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) + for(i = 0; i < numThreads; ++i) + { + memory[i] = calloc(buff_size, sizeof(bwc_float)); + if(memory[i] == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + for(i--; i > 0; --i) { - free(memory[i]); + free(memory[i]); } - free(memory); - return 1; - } - } + free(memory); + return EXIT_FAILURE; + } + } - /*--------------------------------------------------------*\ - ! 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 - { + /*--------------------------------------------------------*\ + ! 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(); + id = omp_get_thread_num(); #else - id = 0; + 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; + for(level = control->numDecomp; level --> 0;) + { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + rX0 = (uint64)parameter->resolution[control->numDecomp - level].info.X0; + rX1 = (uint64)parameter->resolution[control->numDecomp - level].info.X1; + rY0 = (uint64)parameter->resolution[control->numDecomp - level].info.Y0; + rY1 = (uint64)parameter->resolution[control->numDecomp - level].info.Y1; + rZ0 = (uint64)parameter->resolution[control->numDecomp - level].info.Z0; + rZ1 = (uint64)parameter->resolution[control->numDecomp - level].info.Z1; + rTS0 = (uint16)parameter->resolution[control->numDecomp - level].info.TS0; + rTS1 = (uint16)parameter->resolution[control->numDecomp - 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) + if((level < control->numDecompTS) && ((rTS1 - rTS0) > 1)) { - working_buffer++; - } + /*--------------------------------------------------------*\ + ! Associate the working buffer with the appropriate start- ! + ! ing point in the memory block. Adjust the buffer point- ! + ! er in case of an odd starting point in the curr. slice. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsTS]; - /*--------------------------------------------------------*\ - ! 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; + if(rTS0 % 2) + { + working_buffer++; + } - /*--------------------------------------------------------*\ - ! 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) - { + /*--------------------------------------------------------*\ + ! Walk trough all the spatial slices, columns and rows. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp for collapse(3) + #endif + 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) + { + for(x = 0; x < (rX1 - rX0); ++x) { - data[0].f /= 2; + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next temporal slice. ! + \*--------------------------------------------------------*/ + data = parameter->data + x * incr_X + y * incr_Y + z * incr_Z; + + /*--------------------------------------------------------*\ + ! In case the current slice only encompasses 1 value the ! + ! iteration will be skipped. For an odd starting pont, the ! + ! sample will be multiplied by two to manage filter gain. ! + \*--------------------------------------------------------*/ + if((rTS1 - rTS0) == 1) + { + if(rTS0 & 2) + { + data[0] *= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the next tile parameter ! + ! temporal 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); } - 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) - { + if((level < control->numDecompZ) && ((rZ1 - rZ0) > 1)) + { + /*--------------------------------------------------------*\ + ! Associate the working buffer with the appropriate start- ! + ! ing point in the memory block. Adjust the buffer point- ! + ! er in case of an odd starting point in the curr. slice. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsZ]; + + if(rZ0 % 2) + { + working_buffer++; + } + + /*--------------------------------------------------------*\ + ! Walk trough all the temporal slices, columns and rows. ! + \*--------------------------------------------------------*/ + #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 case the current slice only encompasses 1 value the ! + ! iteration will be skipped. For an odd starting pont, the ! + ! sample will be multiplied by two to manage filter gain. ! + \*--------------------------------------------------------*/ + if((rZ1 - rZ0) == 1) + { + if(rZ0 & 2) + { + data[0] /= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the next tile parameter ! + ! 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 ! + ! 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->numDecompY) && ((rY1 - rY0) > 1)) + { + /*--------------------------------------------------------*\ + ! Associate the working buffer with the appropriate start- ! + ! ing point in the memory block. Adjust the buffer point- ! + ! er in case of an odd starting point in the curr. column. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsY]; + + if(rY0 % 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(x = 0; x < (rX1 - rX0); ++x) + { + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next column. ! + \*--------------------------------------------------------*/ + data = parameter->data + x * incr_X + z * incr_Z + t * incr_TS; + + /*--------------------------------------------------------*\ + ! In case the current column only encompasses 1 value the ! + ! iteration will be skipped. For an odd starting pont, the ! + ! sample will be multiplied by two to manage filter gain. ! + \*--------------------------------------------------------*/ + if((rY1 - rY0) == 1) + { + if(rY0 & 2) + { + data[0] /= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the next tile parameter col-! + ! umn. ! + \*--------------------------------------------------------*/ + 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->numDecompX) && ((rX1 - rX0) > 1)) + { + /*--------------------------------------------------------*\ + ! Associate the working buffer with the appropriate start- ! + ! ing point in the memory block. Adjust the buffer point- ! + ! er in case of an odd starting point in the curr. row. ! + \*--------------------------------------------------------*/ + working_buffer = &memory[id][filter_tapsX]; + + if(rX0 % 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(y = 0; y < (rY1 - rY0); ++y) + { + /*--------------------------------------------------------*\ + ! Advance the data pointer to the next row. ! + \*--------------------------------------------------------*/ + data = parameter->data + y * incr_Y + z * incr_Z + t * incr_TS; + + /*--------------------------------------------------------*\ + ! In case the current row only encompasses 1 value the it- ! + ! eration will be skipped. For an odd starting pont, the ! + ! sample will be multiplied by two to manage filter gain. ! + \*--------------------------------------------------------*/ + if((rX1 - rX0) == 1) + { + if(rX0 & 2) + { + data[0] /= 2; + } + continue; + } + + /*--------------------------------------------------------*\ + ! Fill the working buffer with the next tile parameter row.! + \*--------------------------------------------------------*/ + 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 row.! + \*--------------------------------------------------------*/ + 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 buffer array and memory blocks. ! + \*--------------------------------------------------------*/ + for(i = 0; i < numThreads; ++i) + { free(memory[i]); - } - free(memory); + } + free(memory); - return 0; + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/src/library/field.c b/src/library/field.c new file mode 100644 index 0000000..b070697 --- /dev/null +++ b/src/library/field.c @@ -0,0 +1,3680 @@ +/*====================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| Big Whoop is a compression codec for the lossy compression of IEEE 754 floating || +|| point arrays defined on curvelinear compute grids. || +|| || +|| ---------------------------------------------------------------------------------------------------------------- || +|| || +|| 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. || +|| || +\*====================================================================================================================*/ +/**********************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\**********************************************************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "codestream.h" +#include "dwt.h" +#include "macros.h" +#include "tagtree.h" +#include "types.h" + +/**********************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function deallocates the tile structure defining the dyadic decomposition ! +! of a numerical dataset used during (de-)compression. The deallocation will be ! +! carried out down to the substructure that have been allocated. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 17.05.2020 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static void +free_tile(bwc_field *const field) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 c, k; + uint16 p, r; + int8 s; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + bwc_parameter *parameter; + + bwc_resolution *resolution; + + bwc_subband *subband; + + bwc_precinct *precinct; + + bwc_codeblock *codeblock; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = &field->info; + + /*--------------------------------------------------------*\ + ! Walk through and deallocate the tile structure down to ! + ! the substructures that have been allocated. ! + \*--------------------------------------------------------*/ + if(field->setup.tile.parameter != NULL) + { + for(p = 0; p < info->numParams; ++p) + { + parameter = &field->setup.tile.parameter[p]; + if(parameter->resolution != NULL) + { + for(r = 0; r < control->numDecomp + 1; ++r) + { + resolution = ¶meter->resolution[r]; + if(resolution->subband != NULL) + { + for(s = 0; s < resolution->control.numSubbands_a; ++s) + { + subband = &resolution->subband[s]; + if(subband->precinct != NULL) + { + for(k = 0; k < resolution->control.numPrecincts_a; ++k) + { + precinct = &subband->precinct[k]; + if(precinct->codeblock != NULL) + { + for(c = 0; c < precinct->control.numCodeblocks_a; ++c) + { + codeblock = &precinct->codeblock[c]; + if(codeblock->encoded_block.data != NULL) + { + free(codeblock->encoded_block.data); + } + free(codeblock->control.memory); + } + } + if(precinct->control.numCodeblocks != 0) + { + kill_tagtree(&precinct->control.tag_inclusion); + kill_tagtree(&precinct->control.tag_msbs); + } + free(precinct->codeblock); + } + } + free(subband->precinct); + } + } + free(resolution->subband); + free(resolution->packet); + } + } + free(parameter->resolution); + free(parameter->access); + } + } + free(field->setup.tile.packet_sequence); + free(field->setup.tile.parameter); + + /*--------------------------------------------------------*\ + ! Set the remaining pointer in the tile structure to NULL, ! + ! adjust the memory usage and return to the func. caller. ! + \*--------------------------------------------------------*/ + field->setup.tile.packet_sequence = NULL; + field->setup.tile.parameter = NULL; + + field->memory.usage.setup = 0; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function initializes the precinct and its subordinate structures with the ! +! appropriate parameters and sets them up for the tile encoding/decoding ! +! procedures. ! +! If an error is encountered an error flag is returned to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! precinct bwc_precinct* - Precinct control structure. ! +! ! +! dX, dY, dZ, dTS unsigned int(32 bit) - Codeblock offset in relation to ! +! the current subband. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 24.05.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 04.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! 06.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Split the function to an ! +! initialize and reset ! +! routine. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static uchar +initialize_precinct(bwc_field *const field, + bwc_precinct *const precinct) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 cb; + uint64 memory_usage = 0; + + uint64 cbSizeX, cbSizeY; + uint64 cbSizeZ, cbSizeTS; + + uint16 cb_X, cb_Y; + uint16 cb_Z, cb_TS; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + bwc_prec_ctrl *prec_control; + bwc_prec_inf *prec_info; + + bwc_cblk_ctrl *cblk_control; + + /*-----------------------*\ + ! 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->numCodeblocks_a = (uint64)(prec_control->numCbX * + prec_control->numCbY * + prec_control->numCbZ * + prec_control->numCbTS); + + /*--------------------------------------------------------*\ + ! If there are any codeblocks present in the current pre- ! + ! cinct, allocate the codeblock array, walk through it and ! + ! initialize the codeblock structures. ! + \*--------------------------------------------------------*/ + if(prec_control->numCodeblocks_a > 0) + { + precinct->codeblock = calloc(prec_control->numCodeblocks_a, sizeof(bwc_codeblock)); + if(precinct->codeblock == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + memory_usage += (prec_control->numCodeblocks_a * sizeof(bwc_codeblock)); + + 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) + { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + cblk_control = &precinct->codeblock[cb].control; + + /*--------------------------------------------------------*\ + ! Allocate the memory block used to store the coding pass ! + ! contributions for the specified quality layers and setup ! + ! the pointer used to access it. ! + \*--------------------------------------------------------*/ + cblk_control->memory = calloc(control->numLayers + 1, sizeof(int16)); + if(cblk_control->memory == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + + cblk_control->cp_contr = &cblk_control->memory[1]; + memory_usage += ((control->numLayers + 1) * sizeof(int16)); + } + } + } + } + } + /*--------------------------------------------------------*\ + ! Adjust the setup memory usage and return to the function ! + ! caller. ! + \*--------------------------------------------------------*/ + field->memory.usage.setup += memory_usage; + + return EXIT_SUCCESS; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! 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 unsigned in (8 bit) - Flag defining the number and ! +! types of 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 ! +! ---- ------ --------- ------- ----------- ! +! 15.05.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 18.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static uint8 +subband_gain(uint8 highband) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(highband <= DIM_ALL); + + highband -= (highband >> 1) & 0x55; + highband = (highband & 0x33) + ((highband >> 2) & 0x33); + + return (highband + (highband >> 4)) & 0x0F; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function initializes the subband and its subordinate structures with the ! +! appropriate parameters and sets them up for the tile encoding/decoding ! +! procedures. ! +! If an error is encountered an error flag is returned to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! parameter bwc_parameter* - Parameter control structure. ! +! ! +! resolution bwc_resolution* - Resolution control structure. ! +! ! +! subband bwc_subband* - Subband control structure. ! +! ! +! level signed int(32 bit) - Resolution level the subband ! +! belongs to. ! +! ! +! highband unsigned char - Highband-Type represented by the ! +! current subband. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 12.12.2017 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 04.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! 06.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Split the function to a ! +! initialize and reset ! +! routine ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static uchar +initialize_subband(bwc_field *const field, + bwc_parameter *const parameter, + bwc_resolution *const resolution, + bwc_subband *const subband, + int32 const level, + int16 const highband) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 buffX, buffY; + uint64 buffZ, buffTS; + + uint64 memory_usage = 0; + + uint64 p; + + uint64 pSizeX, pSizeY; + uint64 pSizeZ, pSizeTS; + + uint32 Rb; + + uint16 p_X, p_Y; + uint16 p_Z, p_TS; + + int8 decomp_level; + + int8 level_X, level_Y; + int8 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(level <= field->control.numDecomp + 1); + assert(highband <= DIM_ALL); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/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 spatial and temporal decomposi- ! + ! tions according to the resolution level the current ! + ! subband populates. ! + \*--------------------------------------------------------*/ + decomp_level = control->numDecomp - level + 1; + + level_X = (decomp_level > control->numDecompX) ? control->numDecompX : decomp_level; + level_Y = (decomp_level > control->numDecompY) ? control->numDecompY : decomp_level; + level_Z = (decomp_level > control->numDecompZ) ? control->numDecompZ : decomp_level; + level_TS = (decomp_level > control->numDecompTS) ? control->numDecompTS : 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 & DIM_X) >> 0)); + subb_info->Y0 = (uint64)ceil( ((float)param_info->Y0 / (1 << level_Y)) - 0.5 * ((highband & DIM_Y) >> 1)); + subb_info->Z0 = (uint64)ceil( ((float)param_info->Z0 / (1 << level_Z)) - 0.5 * ((highband & DIM_Z) >> 2)); + subb_info->TS0 = (uint16)ceil( ((float)param_info->TS0 / (1 << level_TS)) - 0.5 * ((highband & DIM_TS) >> 3)); + + subb_info->X1 = (uint64)ceil( ((float)param_info->X1 / (1 << level_X)) - 0.5 * ((highband & DIM_X) >> 0)); + subb_info->Y1 = (uint64)ceil( ((float)param_info->Y1 / (1 << level_Y)) - 0.5 * ((highband & DIM_Y) >> 1)); + subb_info->Z1 = (uint64)ceil( ((float)param_info->Z1 / (1 << level_Z)) - 0.5 * ((highband & DIM_Z) >> 2)); + subb_info->TS1 = (uint16)ceil( ((float)param_info->TS1 / (1 << level_TS)) - 0.5 * ((highband & DIM_TS) >> 3)); + + /*--------------------------------------------------------*\ + ! Evaluate the dynamic range and energy gain for the cur- ! + ! rent subband. Store the highband flag and energy gain ! + ! factor in the subband control and info structures. ! + \*--------------------------------------------------------*/ + Rb = PREC_BIT + subband_gain((uint8)highband); + subb_control->highband = highband; + subb_info->dwt_gain = get_dwt_energy_gain(field, highband, 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_eff_step_size = 1; + } + else + { + /*--------------------------------------------------------*\ + ! For a derrived quantization style the (effective) quan- ! + ! tization step size is evaluated according to equation ! + ! (10.26) from JPEG2000 by Taubman & Marcellion (p. 439). ! + \*--------------------------------------------------------*/ + subb_control->qt_exponent = (uint8) control->qt_exponent + ((level == 0) ? 0 : 1 - 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_eff_step_size = (1.0f + ((double)subb_control->qt_mantissa / (1 << 11))); + if(subb_control->qt_exponent > Rb) + { + subb_control->qt_eff_step_size /= pow(2,subb_control->qt_exponent - Rb); + } + else + { + subb_control->qt_eff_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, 1 + subb_control->qt_exponent); + + /*--------------------------------------------------------*\ + ! Evaluate the global precinct size and subband start co- ! + ! ordinates for easy access. ! + \*--------------------------------------------------------*/ + pSizeX = 1 << control->precSizeX; + pSizeY = 1 << control->precSizeY; + pSizeZ = 1 << control->precSizeZ; + pSizeTS = 1 << control->precSizeTS; + + /*--------------------------------------------------------*\ + ! If there are any precincts present in the current sub- ! + ! band, allocate the precinct array, walk through it and ! + ! initialize the precinct structures. ! + \*--------------------------------------------------------*/ + if(res_control->numPrecincts_a > 0) + { + subband->precinct = calloc(res_control->numPrecincts_a, sizeof(bwc_precinct)); + if(subband->precinct == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + memory_usage += (res_control->numPrecincts_a * sizeof(bwc_precinct)); + + 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 frequently used variables/structures to temporary ! + ! 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). ! + \*--------------------------------------------------------*/ + buffX = pSizeX * (p_X + (uint32)floor(res_info->X0 / pSizeX )); + buffY = pSizeY * (p_Y + (uint32)floor(res_info->Y0 / pSizeY )); + buffZ = pSizeZ * (p_Z + (uint32)floor(res_info->Z0 / pSizeZ )); + buffTS = pSizeTS * (p_TS + (uint32)floor(res_info->TS0/ pSizeTS)); + + prec_info->X0 = (uint32)MAX(res_info->X0 , buffX); + prec_info->Y0 = (uint32)MAX(res_info->Y0 , buffY); + prec_info->Z0 = (uint32)MAX(res_info->Z0 , buffZ); + prec_info->TS0 = (uint16)MAX(res_info->TS0, buffTS); + + buffX = pSizeX * (p_X + (uint32)floor(res_info->X0 / pSizeX) + 1); + buffY = pSizeY * (p_Y + (uint32)floor(res_info->Y0 / pSizeY) + 1); + buffZ = pSizeZ * (p_Z + (uint32)floor(res_info->Z0 / pSizeZ) + 1); + buffTS = pSizeTS * (p_TS + (uint32)floor(res_info->TS0/ pSizeTS)+ 1); + + prec_info->X1 = (uint32)MIN(res_info->X1 , buffX); + prec_info->Y1 = (uint32)MIN(res_info->Y1 , buffY); + prec_info->Z1 = (uint32)MIN(res_info->Z1 , buffZ); + prec_info->TS1 = (uint16)MIN(res_info->TS1, buffTS); + + if((control->numDecomp - control->numDecompX) < level) + { + prec_info->X0 = (uint32) ceil(((float)prec_info->X0 / 2) - 0.5 * ((highband & DIM_X) >> 0)); + prec_info->X1 = (uint32) ceil(((float)prec_info->X1 / 2) - 0.5 * ((highband & DIM_X) >> 0)); + } + + if((control->numDecomp - control->numDecompY) < level) + { + prec_info->Y0 = (uint32) ceil(((float)prec_info->Y0 / 2) - 0.5 * ((highband & DIM_Y) >> 1)); + prec_info->Y1 = (uint32) ceil(((float)prec_info->Y1 / 2) - 0.5 * ((highband & DIM_Y) >> 1)); + } + + if((control->numDecomp - control->numDecompZ) < level) + { + prec_info->Z0 = (uint32) ceil(((float)prec_info->Z0 / 2) - 0.5 * ((highband & DIM_Z) >> 2)); + prec_info->Z1 = (uint32) ceil(((float)prec_info->Z1 / 2) - 0.5 * ((highband & DIM_Z) >> 2)); + } + + if((control->numDecomp - control->numDecompTS) < level) + { + prec_info->TS0 = (uint16) ceil(((float)prec_info->TS0 / 2) - 0.5 * ((highband & DIM_TS) >> 3)); + prec_info->TS1 = (uint16) ceil(((float)prec_info->TS1 / 2) - 0.5 * ((highband & DIM_TS) >> 3)); + } + + /*--------------------------------------------------------*\ + ! Initialize the precinct structure according to the spe- ! + ! cified compression parameters and update the number of ! + ! codeblocks for the current parameter. ! + \*--------------------------------------------------------*/ + initialize_precinct(field, &subband->precinct[p]); + + param_control->numCodeblocks += prec_control->numCodeblocks; + } + } + } + } + } + /*--------------------------------------------------------*\ + ! Adjust the setup memory usage and return to the function ! + ! caller. ! + \*--------------------------------------------------------*/ + field->memory.usage.setup += memory_usage; + + return EXIT_SUCCESS; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function allocates the tile structure with the appropriate number of ! +! resolution levels, subbands, precincts and codeblocks necessary to cover the ! +! largest tile in the current numerical dataset. Additionally, it will evaluate ! +! the memory footprint of the fully allocated tile structure. ! +! The function should be called for every numerical dataset before it's tiles are ! +! (de-)compressed. It will not populate the tile structure with all the necessary ! +! parameters needed by the codec. In order to ensure proper processing, the ! +! initialize_tile function has to be followed by the set_up_tile function for ! +! every tile before all of its coding/decoding procedures. ! +! Once the numerical dataset has been (de-)compressed, the free_tile function ! +! should be invoked to free up system memory. ! +! If an error is encountered, the tile structure is properly deallocated and an ! +! error flag is returned to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 14.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Redefined the function ! +! for the new bwc_field ! +! structure. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static uchar +initialize_tile(bwc_field *const field) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 memory_usage = 0; + + uint64 numPackets; + uint64 rem, numTiles; + uint64 index; + + uint32 t, x, y, z; + + int16 r; + + uint8 j; + int8 l, m; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar highband = 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_resolution *resolution; + bwc_res_ctrl *res_control; + bwc_res_inf *res_info; + + bwc_tile *tile; + bwc_tile_inf *tile_info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save the global control and info as well as the tile and ! + ! its info structure to temporary variables to make the ! + ! code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = &field->info; + + tile = &field->setup.tile; + tile_info = tile->info; + + /*--------------------------------------------------------*\ + ! Initialize the memory usage variable. ! + \*--------------------------------------------------------*/ + memory_usage = sizeof(bwc_tile_inf*) + + sizeof(bwc_tile) + 9; + + /*--------------------------------------------------------*\ + ! Allocate and initialize the canvas structure describing ! + ! the tile decomposition of the current datablock. ! + \*--------------------------------------------------------*/ + field->setup.canvas = calloc(control->numTiles, sizeof(bwc_tile_inf)); + if(field->setup.canvas == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + memory_usage += control->numTiles * sizeof(bwc_tile_inf); + + for(index = 0; index < control->numTiles; ++index) + { + /*--------------------------------------------------------*\ + ! Evaluate the spatial and temporal tile indices according ! + ! to the global tile index. ! + \*--------------------------------------------------------*/ + tile_info = &field->setup.canvas[index]; + + numTiles = control->numTiles / control->numTilesTS; + t = index/numTiles; + rem = index%numTiles; + + numTiles = numTiles / control->numTilesZ; + z = rem/numTiles; + rem = rem%numTiles; + + numTiles = numTiles / control->numTilesY; + y = rem/numTiles; + x = rem%numTiles; + + /*--------------------------------------------------------*\ + ! Calculate the borders for the current tile index. ! + \*--------------------------------------------------------*/ + 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); + } + + field->setup.tile.info = & field->setup.canvas[0]; + + /*--------------------------------------------------------*\ + ! Allocate, walk through and setup the parameter struc- ! + ! tures according to the specified compression parameters. ! + \*--------------------------------------------------------*/ + tile->parameter = calloc(info->numParams, sizeof(bwc_parameter)); + if(tile->parameter == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + memory_usage += (info->numParams * sizeof(bwc_parameter)); + + for(j = 0; j < info->numParams; ++j) + { + /*--------------------------------------------------------*\ + ! Extract the linked list node for the current parameter ! + ! index and save the parameter and its info and control ! + ! structures to temporary variables. ! + \*--------------------------------------------------------*/ + for(param = info->parameter->root; param->id != j; param = param->next) + { + if(param == NULL) + { + // invalid paramter ID + fprintf(stderr, PARERROR); + return EXIT_FAILURE; + } + } + + parameter = &tile->parameter[j]; + param_control = ¶meter->control; + param_info = ¶meter->info; + + /*--------------------------------------------------------*\ + ! Save the parameter name and precision in the param. info ! + ! and its sampling factors in the parameter control struct.! + \*--------------------------------------------------------*/ + 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; + + /*--------------------------------------------------------*\ + ! Evaluate the largest possible tile boundaries for the ! + ! current parameter according to equation (11.4) from ! + ! JPEG2000 by Taubman and Marcellin (p. 454). ! + \*--------------------------------------------------------*/ + param_info->X0 = (uint64)0; + param_info->Y0 = (uint64)0; + param_info->Z0 = (uint64)0; + param_info->TS0 = (uint16)0; + + 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- ! + ! tures according to the specified compression parameters. ! + \*--------------------------------------------------------*/ + parameter->resolution = calloc(control->numDecomp + 1, sizeof(bwc_resolution)); + if(parameter->resolution == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + memory_usage += ((control->numDecomp + 1) * sizeof(bwc_resolution)); + + for(r = 0; r < control->numDecomp + 1; ++r) + { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures 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 lev- ! + ! according to the corresponding equation from JPEG2000 by ! + ! David S. Taubman and Michael W. Marcellin (p. 456). ! + \*--------------------------------------------------------*/ + res_info->X0 = 0; + res_info->Y0 = 0; + res_info->Z0 = 0; + res_info->TS0 = 0; + + res_info->X1 = (uint64)ceil((float)param_info->X1 / (1 << MIN(control->numDecomp -r, + control->numDecompX))); + + res_info->Y1 = (uint64)ceil((float)param_info->Y1 / (1 << MIN(control->numDecomp -r, + control->numDecompY))); + + res_info->Z1 = (uint64)ceil((float)param_info->Z1 / (1 << MIN(control->numDecomp -r, + control->numDecompZ))); + + res_info->TS1 = (uint16)ceil((float)param_info->TS1/ (1 << MIN(control->numDecomp -r, + control->numDecompTS))); + + /*--------------------------------------------------------*\ + ! Evaluate the largest possible number of precincts for ! + ! the current resolution level according to equation (11. ! + ! 10) from JPEG 2000 by Taubman and Marcellin (p. 459). ! + \*--------------------------------------------------------*/ + res_control->numPX = (uint16)(ceil((float)res_info->X1 / (1 << control->precSizeX))); + res_control->numPY = (uint16)(ceil((float)res_info->Y1 / (1 << control->precSizeY))); + res_control->numPZ = (uint16)(ceil((float)res_info->Z1 / (1 << control->precSizeZ))); + res_control->numPTS = (uint16)(ceil((float)res_info->TS1 / (1 << control->precSizeTS))); + + + res_control->numPrecincts_a = (uint64)res_control->numPX * res_control->numPY * + res_control->numPZ * res_control->numPTS; + + /*--------------------------------------------------------*\ + ! Evaluate the true codeblock size for the current resolu- ! + ! tion level. ! + \*--------------------------------------------------------*/ + 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 which spatial or temporal directions the wave- ! + ! let decomposition has been applied to according to the ! + ! current resolution level and amend the highband flag. ! + \*--------------------------------------------------------*/ + highband = ((control->numDecomp - control->numDecompX < r) && (r > 0)) ? DIM_X : 0; + highband |= ((control->numDecomp - control->numDecompY < r) && (r > 0)) ? DIM_Y : 0; + highband |= ((control->numDecomp - control->numDecompZ < r) && (r > 0)) ? DIM_Z : 0; + highband |= ((control->numDecomp - control->numDecompTS < r) && (r > 0)) ? DIM_TS : 0; + + /*--------------------------------------------------------*\ + ! Evaluate the overall number of subbands, for the current ! + ! resolution level, according to the highband flag. ! + \*--------------------------------------------------------*/ + res_control->numSubbands_a = (1 << (((highband & DIM_X)) + + ((highband & DIM_Y) >> 1) + + ((highband & DIM_Z) >> 2) + + ((highband & DIM_TS) >> 3))); + + res_control->numSubbands_a -= (res_control->numSubbands_a & 1) ? 0 : 1; + + /*--------------------------------------------------------*\ + ! Allocate the point array used to hold the memory handles ! + ! of all packets created for the current resolution. ! + \*--------------------------------------------------------*/ + numPackets = res_control->numPrecincts_a * control->numLayers; + resolution->packet = calloc(numPackets, sizeof(bwc_packet)); + if(resolution->packet == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + memory_usage += numPackets * sizeof(bwc_packet); + + /*--------------------------------------------------------*\ + ! Allocate, walk through and setup the subband structures ! + ! according to the specified compression parameters. ! + \*--------------------------------------------------------*/ + resolution->subband = calloc(res_control->numSubbands_a, sizeof(bwc_subband)); + if(resolution->subband == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + memory_usage += (res_control->numSubbands_a * sizeof(bwc_subband)); + + for(l = 0, m = 0; m < res_control->numSubbands_a; ++l) + { + if(r == 0 || ((l & highband) == l && l != 0)) + { + if(initialize_subband(field, + parameter, + resolution, + &resolution->subband[m], + r, + l) == EXIT_FAILURE) + { + return EXIT_FAILURE; + } + m++; + } + } + } + + /*--------------------------------------------------------*\ + ! Advance the parameter information linked listed to the ! + ! next node. ! + \*--------------------------------------------------------*/ + param = param->next; + } + + /*--------------------------------------------------------*\ + ! Update the memory usage and return to the function cal- ! + ! ler. ! + \*--------------------------------------------------------*/ + field->memory.usage.setup += memory_usage; + + return EXIT_SUCCESS; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function populates the precinct and its subordinate codeblock structures ! +! with the appropriate parameters and sets them up for the tile encoding/decoding ! +! procedures. ! +! If an error is encountered an error flag is returned to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! precinct bwc_precinct* - Precinct control structure. ! +! ! +! dX, dY, dZ, dTS unsigned int(32 bit) - Codeblock offset in relation to ! +! to the current subband. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 24.05.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 04.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! 06.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Split the function to an ! +! initialize and reset rou- ! +! tine. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static uchar +adapt_precinct(bwc_field *const field, + bwc_precinct *const precinct, + uint32 const dX, + uint32 const dY, + uint32 const dZ, + uint32 const dTS) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 cb; + + uint64 buffX, buffY; + uint64 buffZ, buffTS; + + uint64 cbSizeX, cbSizeY; + uint64 cbSizeZ, cbSizeTS; + + uint16 cb_X, cb_Y; + uint16 cb_Z, cb_TS; + + int16 *tmp; + + /*-----------------------*\ + ! 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->numCodeblocks = (uint64)(prec_control->numCbX * + prec_control->numCbY * + prec_control->numCbZ * + prec_control->numCbTS); + + if((prec_control->numCodeblocks > prec_control->numCodeblocks_a)) + { + printf("Ohhh fuck2 \n"); + } + /*--------------------------------------------------------*\ + ! If there are any codeblocks present in the current pre- ! + ! cinct, reset the inclusion and msbs tagree and walk ! + ! through and set up the codeblock structures. ! + \*--------------------------------------------------------*/ + if(prec_control->numCodeblocks > 0) + { + if(initialize_tagtree(&prec_control->tag_msbs, + prec_control->numCbX, + prec_control->numCbY, + prec_control->numCbZ, + prec_control->numCbTS) == EXIT_FAILURE) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + + if(initialize_tagtree(&prec_control->tag_inclusion, + prec_control->numCbX, + prec_control->numCbY, + prec_control->numCbZ, + prec_control->numCbTS) == EXIT_FAILURE) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + + 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) + { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + codeblock = &precinct->codeblock[cb]; + cblk_info = &codeblock->info; + cblk_control = &codeblock->control; + + /*--------------------------------------------------------*\ + ! Properly reset the codeblock structure. ! + \*--------------------------------------------------------*/ + tmp = cblk_control->memory; + + if(codeblock->encoded_block.data != NULL) + { + free(codeblock->encoded_block.data); + } + + memset(&codeblock->encoded_block, 0, sizeof(bwc_encoded_blk)); + memset(cblk_control, 0, sizeof(bwc_cblk_ctrl)); + memset(tmp, 0, (control->numLayers + 1)); + + cblk_control->memory = tmp; + 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). ! + \*--------------------------------------------------------*/ + buffX = cbSizeX * (cb_X + (uint32)floor((float)prec_info->X0 / cbSizeX)); + buffY = cbSizeY * (cb_Y + (uint32)floor((float)prec_info->Y0 / cbSizeY)); + buffZ = cbSizeZ * (cb_Z + (uint32)floor((float)prec_info->Z0 / cbSizeZ)); + buffTS = cbSizeTS * (cb_TS + (uint32)floor((float)prec_info->TS0/ cbSizeTS)); + + cblk_info->X0 = dX + (uint32)MAX(prec_info->X0 , buffX); + cblk_info->Y0 = dY + (uint32)MAX(prec_info->Y0 , buffY); + cblk_info->Z0 = dZ + (uint32)MAX(prec_info->Z0 , buffZ); + cblk_info->TS0 = dTS + (uint16)MAX(prec_info->TS0, buffTS); + + buffX = cbSizeX * (cb_X + (uint32)floor((float)prec_info->X0 / cbSizeX) + 1); + buffY = cbSizeY * (cb_Y + (uint32)floor((float)prec_info->Y0 / cbSizeY) + 1); + buffZ = cbSizeZ * (cb_Z + (uint32)floor((float)prec_info->Z0 / cbSizeZ) + 1); + buffTS = cbSizeTS * (cb_TS + (uint32)floor((float)prec_info->TS0/ cbSizeTS) + 1); + + cblk_info->X1 = dX + (uint32)MIN(prec_info->X1 , buffX); + cblk_info->Y1 = dY + (uint32)MIN(prec_info->Y1 , buffY); + cblk_info->Z1 = dZ + (uint32)MIN(prec_info->Z1 , buffZ); + cblk_info->TS1 = dTS + (uint16)MIN(prec_info->TS1, buffTS); + } + } + } + } + } + return EXIT_SUCCESS; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function populates the subband and its subordinate structures with the ! +! appropriate parameters and sets them up for the tile encoding/decoding ! +! procedures. ! +! If an error is encountered an error flag is returned to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! parameter bwc_parameter* - Parameter control structure. ! +! ! +! resolution bwc_resolution* - Resolution control structure. ! +! ! +! subband bwc_subband* - Subband control structure. ! +! ! +! level signed int(32 bit) - Resolution level the subband ! +! belongs to. ! +! ! +! highband unsigned char - Highband-Type represented by the ! +! current subband. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 12.12.2017 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 04.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! 06.05.2020 Patrick Vogler B87E7E4 V 0.1.0 split the function to a ! +! initialize and reset ! +! routine ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static uchar +adapt_subband(bwc_field *const field, + bwc_parameter *const parameter, + bwc_resolution *const resolution, + bwc_subband *const subband, + int32 const level, + int16 const highband) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 buffX, buffY; + uint64 buffZ, buffTS; + + uint64 p; + + uint64 pSizeX, pSizeY; + uint64 pSizeZ, pSizeTS; + + uint64 sb_sX, sb_sY; + uint64 sb_sZ, sb_sTS; + + uint16 p_X, p_Y; + uint16 p_Z, p_TS; + + int8 decomp_level; + + int8 level_X, level_Y; + int8 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_inf *subb_info; + + bwc_prec_ctrl *prec_control; + bwc_prec_inf *prec_info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(resolution); + assert(subband); + assert(level <= field->control.numDecomp + 1); + assert(highband <= DIM_ALL); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/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_info = &subband->info; + + /*--------------------------------------------------------*\ + ! Evaluate the number of spatial and temporal decomposi- ! + ! tions according to the resolution level the current ! + ! subband populates. ! + \*--------------------------------------------------------*/ + decomp_level = control->numDecomp - level + 1; + + level_X = (decomp_level > control->numDecompX) ? control->numDecompX : decomp_level; + level_Y = (decomp_level > control->numDecompY) ? control->numDecompY : decomp_level; + level_Z = (decomp_level > control->numDecompZ) ? control->numDecompZ : decomp_level; + level_TS = (decomp_level > control->numDecompTS) ? control->numDecompTS : 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 & DIM_X) >> 0)) ); + subb_info->Y0 = (uint64)ceil( ((float)param_info->Y0 / (1 << level_Y)) - (0.5 * ((highband & DIM_Y) >> 1)) ); + subb_info->Z0 = (uint64)ceil( ((float)param_info->Z0 / (1 << level_Z)) - (0.5 * ((highband & DIM_Z) >> 2)) ); + subb_info->TS0 = (uint16)ceil( ((float)param_info->TS0 / (1 << level_TS)) - (0.5 * ((highband & DIM_TS) >> 3)) ); + + subb_info->X1 = (uint64)ceil( ((float)param_info->X1 / (1 << level_X)) - (0.5 * ((highband & DIM_X) >> 0)) ); + subb_info->Y1 = (uint64)ceil( ((float)param_info->Y1 / (1 << level_Y)) - (0.5 * ((highband & DIM_Y) >> 1)) ); + subb_info->Z1 = (uint64)ceil( ((float)param_info->Z1 / (1 << level_Z)) - (0.5 * ((highband & DIM_Z) >> 2)) ); + subb_info->TS1 = (uint16)ceil( ((float)param_info->TS1 / (1 << level_TS)) - (0.5 * ((highband & DIM_TS) >> 3)) ); + + /*--------------------------------------------------------*\ + ! Evaluate the global precinct size and subband start co- ! + ! ordinates for easy access. ! + \*--------------------------------------------------------*/ + pSizeX = 1 << control->precSizeX; + pSizeY = 1 << control->precSizeY; + pSizeZ = 1 << control->precSizeZ; + pSizeTS = 1 << control->precSizeTS; + + sb_sX = (highband & DIM_X) ? (parameter->resolution[level - 1].info.X1 - + parameter->resolution[level - 1].info.X0 ) : 0; + sb_sY = (highband & DIM_Y) ? (parameter->resolution[level - 1].info.Y1 - + parameter->resolution[level - 1].info.Y0 ) : 0; + sb_sZ = (highband & DIM_Z) ? (parameter->resolution[level - 1].info.Z1 - + parameter->resolution[level - 1].info.Z0 ) : 0; + sb_sTS = (highband & DIM_TS) ? (parameter->resolution[level - 1].info.TS1 - + parameter->resolution[level - 1].info.TS0) : 0; + + /*--------------------------------------------------------*\ + ! Walk through and set up all precinct structures that are ! + ! present in the current subband. ! + \*--------------------------------------------------------*/ + if(res_control->numPrecincts > 0) + { + 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 frequently used variables/structures to temporary ! + ! 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). ! + \*--------------------------------------------------------*/ + buffX = pSizeX * (p_X + (uint32)floor(res_info->X0 / pSizeX )); + buffY = pSizeY * (p_Y + (uint32)floor(res_info->Y0 / pSizeY )); + buffZ = pSizeZ * (p_Z + (uint32)floor(res_info->Z0 / pSizeZ )); + buffTS = pSizeTS * (p_TS + (uint32)floor(res_info->TS0/ pSizeTS)); + + prec_info->X0 = (uint32)MAX(res_info->X0 , buffX); + prec_info->Y0 = (uint32)MAX(res_info->Y0 , buffY); + prec_info->Z0 = (uint32)MAX(res_info->Z0 , buffZ); + prec_info->TS0 = (uint16)MAX(res_info->TS0, buffTS); + + buffX = pSizeX * (p_X + (uint32)floor(res_info->X0 / pSizeX) + 1); + buffY = pSizeY * (p_Y + (uint32)floor(res_info->Y0 / pSizeY) + 1); + buffZ = pSizeZ * (p_Z + (uint32)floor(res_info->Z0 / pSizeZ) + 1); + buffTS = pSizeTS * (p_TS + (uint32)floor(res_info->TS0/ pSizeTS)+ 1); + + prec_info->X1 = (uint32)MIN(res_info->X1 , buffX); + prec_info->Y1 = (uint32)MIN(res_info->Y1 , buffY); + prec_info->Z1 = (uint32)MIN(res_info->Z1 , buffZ); + prec_info->TS1 = (uint16)MIN(res_info->TS1, buffTS); + + if((control->numDecomp - control->numDecompX) < level) + { + prec_info->X0 = (uint32) ceil(((float)prec_info->X0 / 2) - 0.5 * ((highband & DIM_X) >> 0)); + prec_info->X1 = (uint32) ceil(((float)prec_info->X1 / 2) - 0.5 * ((highband & DIM_X) >> 0)); + } + + if((control->numDecomp - control->numDecompY) < level) + { + prec_info->Y0 = (uint32) ceil(((float)prec_info->Y0 / 2) - 0.5 * ((highband & DIM_Y) >> 1)); + prec_info->Y1 = (uint32) ceil(((float)prec_info->Y1 / 2) - 0.5 * ((highband & DIM_Y) >> 1)); + } + + if((control->numDecomp - control->numDecompZ) < level) + { + prec_info->Z0 = (uint32) ceil(((float)prec_info->Z0 / 2) - 0.5 * ((highband & DIM_Z) >> 2)); + prec_info->Z1 = (uint32) ceil(((float)prec_info->Z1 / 2) - 0.5 * ((highband & DIM_Z) >> 2)); + } + + if((control->numDecomp - control->numDecompTS) < level) + { + prec_info->TS0 = (uint16) ceil(((float)prec_info->TS0 / 2) - 0.5 * ((highband & DIM_TS) >> 3)); + prec_info->TS1 = (uint16) ceil(((float)prec_info->TS1 / 2) - 0.5 * ((highband & DIM_TS) >> 3)); + } + + /*--------------------------------------------------------*\ + ! Reset the precinct structure according to the specified ! + ! compression parameters and update the number of code- ! + ! blocks for the current parameter. ! + \*--------------------------------------------------------*/ + if(adapt_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) == EXIT_FAILURE) + { + return EXIT_FAILURE; + } + + param_control->numCodeblocks += prec_control->numCodeblocks; + } + } + } + } + } + return EXIT_SUCCESS; +} + +/**********************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function initializes the field structure for a (de-)compression run. The ! +! global control structure is rounded out with all necessary standard parameters ! +! wherever no values have been defined by the user. The tile structure and look up ! +! table, used to calculate the energy gain of the multi dimensional wavelet ! +! transform, are initialized. ! +! If an error is encountered the tile structure an error flag is returned to the ! +! function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 18.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Redefined for streaming ! +! functionality. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +uchar +create_field(bwc_field *const field) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 limit; + uint64 size; + + uint64 memory_usage; + + uint8 levelsX, levelsY; + uint8 levelsZ, levelsTS; + + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + double buff; + bwc_float delta; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = &field->info; + + /*--------------------------------------------------------*\ + ! Initialize the codec precision in the info structure ! + ! and, unless otherwise specified by the user, set the ! + ! number of threads to its default value. ! + \*--------------------------------------------------------*/ + info->codec_prec = PREC_BYTE; + if(control->numThreads == 0) + { + control->numThreads = 1; + } + + /*--------------------------------------------------------*\ + ! Unless otherwise stated by the user, set the tile size ! + ! and number of tiles to their standard values. Allocate ! + ! the packed tile sizes array. ! + \*--------------------------------------------------------*/ + if(control->CSsgc ^ (0x01 << 0)) + { + control->tileSizeX = info->nX; + control->tileSizeY = info->nY; + control->tileSizeZ = info->nZ; + control->tileSizeTS = info->nTS; + + control->numTilesX = 1; + control->numTilesY = 1; + control->numTilesZ = 1; + control->numTilesTS = 1; + + control->numTiles = 1; + } + + control->packed_tile_size = calloc(control->numTiles, sizeof(uint64)); + if(control->packed_tile_size == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + field->memory.usage.codestream += (control->numTiles * sizeof(uint64)); + + /*--------------------------------------------------------*\ + ! Unless otherwise stated by the user, set the wavelet ! + ! kernels to their standard values. ! + \*--------------------------------------------------------*/ + if(control->CSsgc ^ (0x01 << 1)) + { + control->KernelX = + control->KernelY = + control->KernelZ = + control->KernelTS = bwc_dwt_9_7; + } + + /*--------------------------------------------------------*\ + ! Unless otherwise stated by the user, set the spatial, ! + ! temporal and maximum number of decomposition levels to ! + ! their standard values. ! + \*--------------------------------------------------------*/ + if(control->CSsgc ^ (0x01 << 2)) + { + levelsX = log(info->nX) /log(2); + levelsY = log(info->nY) /log(2); + levelsZ = log(info->nZ) /log(2); + levelsTS = log(info->nTS)/log(2); + + control->numDecompX = (info->nX >> 1) ? ((4 < levelsX) ? 4 : levelsX) : 0; + control->numDecompY = (info->nY >> 1) ? ((4 < levelsY) ? 4 : levelsY) : 0; + control->numDecompZ = (info->nZ >> 1) ? ((4 < levelsZ) ? 4 : levelsZ) : 0; + control->numDecompTS = (info->nTS >> 1) ? ((4 < levelsTS) ? 4 : levelsTS) : 0; + + control->numDecomp = MAX(control->numDecompX, + MAX(control->numDecompY, + MAX(control->numDecompZ, control->numDecompTS))); + } + + /*--------------------------------------------------------*\ + ! Unless otherwise stated by the user, set the precinct ! + ! codeblock sizes to their standard values. ! + \*--------------------------------------------------------*/ + if(control->CSsgc ^ (0x01 << 3)) + { + 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; + } + + if(control->CSsgc ^ (0x01 << 4)) + { + 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; + } + + /*--------------------------------------------------------*\ + ! Unless otherwise stated by the user, set the progression ! + ! order, quantization style and Q number format range to ! + ! their standard values. ! + \*--------------------------------------------------------*/ + if(control->CSsgc ^ (0x01 << 5)) + { + control->progression = bwc_prog_LRCP; + } + + if(control->CSsgc ^ (0x01 << 7)) + { + control->quantization_style = bwc_qt_derived; + } + + if(control->CSsgc ^ (0x01 << 8)) + { + control->Qm = PREC_BIT - 1; + } + + /*--------------------------------------------------------*\ + ! Initialize the discrete wavelet transform energy gain ! + ! look-up tables. ! + \*--------------------------------------------------------*/ + field->setup.flag = SETUP_CMP; + + if(initialize_gain_lut() == EXIT_FAILURE) + { + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Unless otherwise specified by the user, evaluate mantis- ! + ! sa and exponent for the quantization step size. ! + \*--------------------------------------------------------*/ + if(control->CSsgc ^ (0x01 << 9)) + { + delta = (bwc_float)(1/(pow(2, 2 + PREC_BIT) * sqrt(get_dwt_energy_gain(field, 0, control->numDecomp)))); + + 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; + } + } + } + + /*--------------------------------------------------------*\ + ! Initialize the tile structure. ! + \*--------------------------------------------------------*/ + if(initialize_tile(field) == EXIT_FAILURE) + { + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Make sure that the input and ouput streams are properly ! + ! initialized for a (de-)compression run. ! + \*--------------------------------------------------------*/ + if(((field->setup.flag & SETUP_CMP) != 0) && + (field->data.flag == DATA_CLR)) + { + // no input specified + fprintf(stderr, INPERROR); + return EXIT_FAILURE; + } + else if(((field->setup.flag & SETUP_DCP) != 0) && + (field->codestream.flag == CS_CLR)) + { + // no input specified + fprintf(stderr, INPERROR); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Allocate the required working buffer if the data-set is ! + ! not streamed to/from a file. ! + \*--------------------------------------------------------*/ + size = control->tileSizeX * control->tileSizeY * + control->tileSizeZ * control->tileSizeTS; + + if((field->data.flag & DATA_STR) == 0) + { + field->setup.working_buffer.size = size; + + field->setup.working_buffer.access = + field->setup.working_buffer.memory = calloc(size, sizeof(bwc_float)); + if(field->setup.working_buffer.memory == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + } + + /*--------------------------------------------------------*\ + ! Initialize the main header for a compression run. ! + \*--------------------------------------------------------*/ + if((field->setup.flag & SETUP_CMP) != 0) + { + if(initialize_main_header(field) == EXIT_FAILURE) + { + return EXIT_FAILURE; + } + } + + /*--------------------------------------------------------*\ + ! If the streaming option has been turned on, evaluate the ! + ! number of datastreams that can be held in memory. ! + \*--------------------------------------------------------*/ + if(((field->data.flag & DATA_STR) == 0) || + ((field->codestream.flag & CS_STR) == 0)) + { + memory_usage = field->memory.usage.codestream + + field->memory.usage.data + + field->memory.usage.setup + + field->memory.usage.stat; + + if(field->memory.limit > memory_usage) + { + buff = (float)((field->memory.limit - memory_usage)/(size * sizeof(bwc_float))); + buff -= floor((buff - control->bitrate[control->numLayers])/sizeof(bwc_float)); + } + else + { + buff = 1; + } + } + + /*--------------------------------------------------------*\ + ! Set up the packed data streams according to the user de- ! + ! fined streaming settings. ! + \*--------------------------------------------------------*/ + if(((field->data.flag & DATA_STR) == 0) || (buff < 2)) + limit = 1; + else + limit = (uint64)buff; + + field->data.body = calloc(limit, sizeof(bwc_packed_stream)); + if(field->data.body == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + field->data.limit = limit; + + /*--------------------------------------------------------*\ + ! Set up the packed codestream streams according to the ! + ! user defined streaming settings. ! + \*--------------------------------------------------------*/ + if(((field->codestream.flag & CS_STR) == 0) || (buff < 2)) + limit = 1; + else + limit = (uint64)buff; + + field->codestream.body = calloc(limit, sizeof(bwc_packed_stream)); + if(field->codestream.body == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + field->codestream.limit = limit; + + return EXIT_SUCCESS; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function populates the tile structure with the appropriate parameters for ! +! the tile identified by the supplied indexsets it up for encoding/decoding. If an ! +! error is encountered the tile structure is properly deallocated and an error ! +! flag is returned to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! index unsigned int(64 bit) - Tile index. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 14.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Redefined the function ! +! for the new bwc_field ! +! structure. ! +! 06.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Split the function to an ! +! initialize and reset ! +! routine. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +uchar +adapt_tile(bwc_field *const field, + uint64 const index) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 numPackets = 0; + uint64 cblk, pa; + + uint32 c, pr; + + int16 r; + + uint8 p; + int8 h, l, s; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar highband = 0; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + bwc_cblk_access *access_tmp; + + bwc_parameter *parameter; + bwc_param_ctrl *param_control; + bwc_param_inf *param_info; + + bwc_packet **packet_sequence; + bwc_packet *packet; + + bwc_resolution *resolution; + bwc_res_ctrl *res_control; + bwc_res_inf *res_info; + + bwc_subband *subband; + + bwc_tile *tile; + bwc_tile_ctrl *tile_control; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = &field->info; + + tile = &field->setup.tile; + tile_control = &tile->control; + + /*--------------------------------------------------------*\ + ! Associate the tile info structure with the appropriate ! + ! canvas block and initialize the convex hull slope ! + ! threshold. ! + \*--------------------------------------------------------*/ + tile->info = &field->setup.canvas[index]; + + tile_control->slope_max = 0x0000; + tile_control->slope_min = 0xFFFF; + + for(p = 0; p < info->numParams; ++p) + { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + parameter = &tile->parameter[p]; + param_control = ¶meter->control; + param_info = ¶meter->info; + + /*--------------------------------------------------------*\ + ! 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)); + + /*--------------------------------------------------------*\ + ! Initialize the number of codeblocks for the current pa- ! + ! rameter. ! + \*--------------------------------------------------------*/ + param_control->numCodeblocks = 0; + + /*--------------------------------------------------------*\ + ! Walk through and set the resolution structure according ! + ! to the specified tile index and compression parameters. ! + \*--------------------------------------------------------*/ + for(r = 0, cblk = 0; r < control->numDecomp + 1; ++r) + { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures 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->numDecomp -r, + control->numDecompX))); + res_info->Y0 = (uint64)ceil((float)param_info->Y0 / (1 << MIN(control->numDecomp -r, + control->numDecompY))); + res_info->Z0 = (uint64)ceil((float)param_info->Z0 / (1 << MIN(control->numDecomp -r, + control->numDecompZ))); + res_info->TS0 = (uint16)ceil((float)param_info->TS0/ (1 << MIN(control->numDecomp -r, + control->numDecompTS))); + + res_info->X1 = (uint64)ceil((float)param_info->X1 / (1 << MIN(control->numDecomp -r, + control->numDecompX))); + res_info->Y1 = (uint64)ceil((float)param_info->Y1 / (1 << MIN(control->numDecomp -r, + control->numDecompY))); + res_info->Z1 = (uint64)ceil((float)param_info->Z1 / (1 << MIN(control->numDecomp -r, + control->numDecompZ))); + res_info->TS1 = (uint16)ceil((float)param_info->TS1/ (1 << MIN(control->numDecomp -r, + control->numDecompTS))); + + /*--------------------------------------------------------*\ + ! Calculate the number of precincts/packets for the cur- ! + ! rent resolution level according to equation (11.10) from ! + ! JPEG2000 by D. S. Taubman and M. W. Marcellin (p.459). ! + \*--------------------------------------------------------*/ + if(res_info->X0 == res_info->X1) + res_control->numPX = (uint16)0; + else + res_control->numPX = (uint16)(ceil((float)res_info->X1 / (1 << control->precSizeX) - + floor((float)res_info->X0 / (1 << control->precSizeX)))); + + if(res_info->Y0 == res_info->Y1) + res_control->numPY = (uint16)0; + else + res_control->numPY = (uint16)(ceil((float)res_info->Y1 / (1 << control->precSizeY) - + floor((float)res_info->Y0 / (1 << control->precSizeY)))); + + if(res_info->Z0 == res_info->Z1) + res_control->numPZ = (uint16)0; + else + res_control->numPZ = (uint16)(ceil((float)res_info->Z1 / (1 << control->precSizeZ) - + floor((float)res_info->Z0 / (1 << control->precSizeZ)))); + + if(res_info->TS0 == res_info->TS1) + res_control->numPTS = (uint16)0; + else + res_control->numPTS = (uint16)(ceil((float)res_info->TS1 / (1 << control->precSizeTS) - + floor((float)res_info->TS0 / (1 << control->precSizeTS)))); + + + res_control->numPrecincts = (uint64)res_control->numPX * res_control->numPY * + res_control->numPZ * res_control->numPTS; + + numPackets += (res_control->numPrecincts * control->numLayers); + + /*--------------------------------------------------------*\ + ! Evaluate the highband flag according to the spatial and ! + ! temporal wavelet decompositions applied to the current ! + ! subband. ! + \*--------------------------------------------------------*/ + highband = (control->numDecomp - control->numDecompX < r && r > 0) ? DIM_X : 0; + highband |= (control->numDecomp - control->numDecompY < r && r > 0) ? DIM_Y : 0; + highband |= (control->numDecomp - control->numDecompZ < r && r > 0) ? DIM_Z : 0; + highband |= (control->numDecomp - control->numDecompTS < r && r > 0) ? DIM_TS : 0; + + /*--------------------------------------------------------*\ + ! Evaluate the overall number of subbands, for the current ! + ! resolution level, according to the highband flag. ! + \*--------------------------------------------------------*/ + res_control->numSubbands = (1 << (((highband & DIM_X)) + + ((highband & DIM_Y) >> 1) + + ((highband & DIM_Z) >> 2) + + ((highband & DIM_TS) >> 3))); + + res_control->numSubbands -= (res_control->numSubbands & 1) ? 0 : 1; + + /*--------------------------------------------------------*\ + ! Allocate, walk through and setup the subband structures ! + ! according to the specified compression parameters. ! + \*--------------------------------------------------------*/ + if((res_control->numPrecincts > res_control->numPrecincts_a) || + (res_control->numSubbands > res_control->numSubbands_a)) + { + printf("Ohhh fuck \n"); + } + for(h = 0, s = 0; s < res_control->numSubbands; ++h) + { + if(r == 0 || ((h & highband) == h && h != 0)) + { + if(adapt_subband(field, + parameter, + resolution, + &resolution->subband[s], + r, + h) == EXIT_FAILURE) + { + free_tile(field); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Adjust the size of the codeblock access array. ! + \*--------------------------------------------------------*/ + access_tmp = realloc(parameter->access, param_control->numCodeblocks * + sizeof(bwc_cblk_access)); + if(access_tmp == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free_tile(field); + return EXIT_FAILURE; + } + else + { + parameter->access = access_tmp; + } + + /*--------------------------------------------------------*\ + ! Initialize the codeblock access array with the appropri- ! + ! ate precinct, subband and codeblock pointers and set the ! + ! proper indices in the codeblock and packet structures. ! + \*--------------------------------------------------------*/ + for(pr = 0; pr < res_control->numPrecincts; ++pr) + { + subband = &resolution->subband[s]; + + for(c = 0; c < subband->precinct[pr].control.numCodeblocks; ++cblk, ++c) + { + parameter->access[cblk].subband = subband; + parameter->access[cblk].precinct = &subband->precinct[pr]; + parameter->access[cblk].codeblock = &subband->precinct[pr].codeblock[c]; + + parameter->access[cblk].codeblock->info.idx = c; + + for(l = 0; l < control->numLayers; ++l) + { + packet = &resolution->packet[l * res_control->numPrecincts + pr]; + + packet->p = p; + packet->r = r; + packet->pr = pr; + packet->l = l; + } + } + } + s++; + } + } + } + } + + /*--------------------------------------------------------*\ + ! Adjust the packet sequence array size according to the ! + ! number of packets present in the current tile and save ! + ! the number of packets in the tile control structure. ! + \*--------------------------------------------------------*/ + packet_sequence = realloc(tile->packet_sequence, numPackets * sizeof(bwc_packet)); + if(packet_sequence == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free_tile(field); + return EXIT_FAILURE; + } + + tile_control->numPackets = numPackets; + + /*--------------------------------------------------------*\ + ! Loop over the tile packets according to the user speci- ! + ! fied progression order and set up the packet sequence. ! + \*--------------------------------------------------------*/ + switch(control->progression) + { + /*--------------------------------------------------------*\ + ! Quality Layer | Resolution Level | Codeblock | Precinct. ! + \*--------------------------------------------------------*/ + case bwc_prog_LRCP: + { + for(l = 0, pa = 0; l < control->numLayers; ++l) + { + for(r = 0; r < control->numDecomp + 1; ++r) + { + for(p = 0; p < info->numParams; ++p) + { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + resolution = &tile->parameter[p].resolution[r]; + + /*--------------------------------------------------------*\ + ! Loop over all precincts and store the packet structure ! + ! addresses in the packet sequence structure. ! + \*--------------------------------------------------------*/ + for(pr = 0; pr < resolution->control.numPrecincts; ++pr, ++pa) + { + packet_sequence[pa] = &resolution->packet[l * resolution->control.numPrecincts + pr]; + } + } + } + } + break; + } + + /*--------------------------------------------------------*\ + ! If the specified progression order is unknown free the ! + ! field structure and return an error flag to the function ! + ! caller. ! + \*--------------------------------------------------------*/ + default: + { + free_tile(field); + return EXIT_FAILURE; + } + } + + /*--------------------------------------------------------*\ + ! If sequencing was successful, store the corresponding ! + ! pointer in the tile structure and return to the func- ! + ! tion caller. ! + \*--------------------------------------------------------*/ + tile->packet_sequence = packet_sequence; + + return EXIT_SUCCESS; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function allocates the field structure. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! nX ,nY, nZ, nTS unsigned int(64 bit) - Spatial and temporal size of ! +! an uncompressed dataset. ! +! ! +! numParams unsigned int(8 bit) - Number of parameters in the ! +! uncompressed dataset. ! +! ! +! mode uchar* - File extension of an ! +! uncompressed. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! bwc_field* - Codec control structure. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 18.03.2021 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +bwc_field* +bwc_initialize_field(uint64 const nX, + uint64 const nY, + uint64 const nZ, + uint64 const nTS, + uint8 const numParams, + char const mode) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_field *field; + + /*--------------------------------------------------------*\ + ! Verify that only a compression 'c' or decompression 'd' ! + ! mode has been specified. ! + \*--------------------------------------------------------*/ + if((mode != 'c') && (mode != 'd')) + { + //Wrong bwc mode + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Invalid Mode |\n"\ + "| |\n"\ + "| The bwc_field structure can only be setup |\n"\ + "| for compressio 'c' or decompression 'd'. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Allocate the field structure and set the appropriate ! + ! flags per the mode supplied by the function caller. ! + \*--------------------------------------------------------*/ + field = calloc(1, sizeof(bwc_field)); + if(field == NULL) + { + fprintf(stderr, MEMERROR); + return NULL; + } + + if(mode == 'c') + { + field->flag = SETUP_CMP; + field->data.flag = DATA_IN; + field->codestream.flag = CS_OUT; + } + else + { + field->flag = SETUP_DCP; + field->data.flag = DATA_OUT; + field->codestream.flag = CS_IN; + } + + /*--------------------------------------------------------*\ + ! Allocate the field structure and set the appropriate ! + ! flags per the mode supplied by the function caller. ! + \*--------------------------------------------------------*/ + field->info.nX = nX; + field->info.nY = nY; + field->info.nZ = nZ; + field->info.nTS = nTS; + + field->info.numParams = numParams; + + return 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* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 03.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Adapted to new struct ! +! layout. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +bwc_free_field(bwc_field *const field) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_inf *info; + bwc_cmd_opts_ll *param, *temp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + if(field) + { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + info = &field->info; + + /*--------------------------------------------------------*\ + ! Deallocate the parameter linked list stored in the glob- ! + ! al stored in the global info structure. ! + \*--------------------------------------------------------*/ + if(info->parameter != NULL) + { + param = info->parameter->root; + + while(param != NULL) + { + temp = param; + param = param -> next; + free(temp); + } + } + + /*--------------------------------------------------------*\ + ! Deallocate the compression setup structure down to the ! + ! structure levels that have been allocated. ! + \*--------------------------------------------------------*/ + free_tile(field); + + free(field->setup.canvas); + free(field->control.packed_tile_size); + + memset(&field->control, 0, sizeof(bwc_gl_ctrl)); + memset(&field->info, 0, sizeof(bwc_gl_inf)); + + /*--------------------------------------------------------*\ + ! Free the codestream structure. ! + \*--------------------------------------------------------*/ + if(field->codestream.flag != DATA_CLR) + { + free_bwc(field); + } + + /*--------------------------------------------------------*\ + ! Free the data substructure. ! + \*--------------------------------------------------------*/ + if(field->data.flag != DATA_CLR) + { + field->data.free(field); + } + + /*--------------------------------------------------------*\ + ! Free the field structure and return to the function cal- ! + ! ler. ! + \*--------------------------------------------------------*/ + free(field); + } +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function initializes and adds new parameters to the parameter linked list. ! +! The linked list stores the parameter's name, its precision, sampling factor, the ! +! dimension for which the sampling is active and the parameter size after ! +! sub-sampling. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! name char* - Parameters name. ! +! ! +! sample unsigned int(16 bit) - Parameter sampling factor. ! +! ! +! dim unsigned char - Active dimensions for the ! +! sampling factor. ! +! ! +! precision unsigned int(8 bit) - Parameter bit precision. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 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. ! +! 14.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Redefined the function ! +! for the new bwc_field ! +! structure. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +bwc_add_param(bwc_field *const field, + char const *const name, + uint16 const sample, + uchar const dim, + uint8 const precision) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_inf *info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(dim <= DIM_ALL); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + info = &field->info; + + /*--------------------------------------------------------*\ + ! Check if the specified parameter name has the proper ! + ! length and make sure that the supplied parameter preci- ! + ! sion has a valid value. ! + \*--------------------------------------------------------*/ + 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); + } + + if((precision != 8) & + (precision != 4)) + { + // Invalid precision + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Invalid precision |\n"\ + "| |\n"\ + "| The supplied parameter precision is invalid. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return; + } + + /*--------------------------------------------------------*\ + ! Check if the function is called for the first time. If ! + ! true, allocate and initialize the linked list. If not, ! + ! allocate and initialize a new linked list node. ! + \*--------------------------------------------------------*/ + if(info->parameter == NULL) + { + info->parameter = calloc(1, sizeof(bwc_cmd_opts_ll)); + if(info->parameter == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return; + } + + info->parameter->root = info->parameter; + } + else + { + info->parameter->next = calloc(1, sizeof(bwc_cmd_opts_ll)); + if(info->parameter->next == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return; + } + + 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 precision, samp- ! + ! ling value, the dimension for which the sampling is ac- ! + ! tive and the parameter size in the new node. ! + \*--------------------------------------------------------*/ + strcpy(info->parameter->name, name ? name : "undefined"); + info->parameter->precision = precision ? precision : PREC_BYTE; + info->parameter->sample = (sample < 64) ? sample : 0; + info->parameter->dim = dim ? dim : (DIM_X | DIM_Y | DIM_Z); + + info->parameter->size = (uint64)ceil((float)info->nX / (1 << ((dim & DIM_X) ? sample : 0))) * + (uint64)ceil((float)info->nY / (1 << ((dim & DIM_Y) ? sample : 0))) * + (uint64)ceil((float)info->nZ / (1 << ((dim & DIM_Z) ? sample : 0))) * + (uint64)ceil((float)info->nTS / (1 << ((dim & DIM_TS) ? sample : 0))); +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the tile size and number of 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. For all invalid dimensions (n = 1), as well as ! +! all values that have not been specified, the tile size is set to the size of the ! +! numerical dataset. ! +! In case of an error, all tile values are reset and a warning is issued. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! tilesX, -Y, -Z, -TS unsigned int(64 bit) - Spatial and temporal size of a ! +! spatial 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 ! +! ---- ------ --------- ------- ----------- ! +! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 29.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +bwc_set_tiles(bwc_field *const field, + uint64 const tilesX, + uint64 const tilesY, + uint64 const tilesZ, + uint64 const tilesTS, + bwc_tile_instr const instr) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(instr == bwc_tile_sizeof || + instr == bwc_tile_numbof); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures 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 specified tile sizes are invalid. If true, ! + ! issue a warning and return to the function caller. ! + \*--------------------------------------------------------*/ + if((tilesX < 16 && (tilesX > info->nX)) || + (tilesY < 16 && (tilesY > info->nY)) || + (tilesZ < 16 && (tilesZ > info->nZ)) || + (tilesTS < 16 && (tilesTS > info->nTS))) + { + fprintf(stderr,"o==========================================================o\n"\ + "| WARNING: Invalid value |\n"\ + "| |\n"\ + "| One or more of the specified tile di- |\n"\ + "| mensions has a value that falls out- |\n"\ + "| side of its valid range. Please verify |\n"\ + "| that all tile dimension are within the |\n"\ + "| range of: |\n"\ + "| |\n"\ + "| 16 ≤ Tile_Size_Xi ≤ Grid_Points_Xi |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + return; + } + + /*--------------------------------------------------------*\ + ! Amend the tile size in the bwc_field structure according ! + ! to the specified values and evaluate the global number ! + ! of tiles. ! + \*--------------------------------------------------------*/ + 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; + + control->numTilesX = (uint64)ceil(((float)info->nX / control->tileSizeX)); + control->numTilesY = (uint64)ceil(((float)info->nY / control->tileSizeY)); + control->numTilesZ = (uint64)ceil(((float)info->nZ / control->tileSizeZ)); + control->numTilesTS = (uint16)ceil(((float)info->nTS / control->tileSizeTS)); + + control->numTiles = control->numTilesX * control->numTilesY * + control->numTilesZ * control->numTilesTS; + + /*--------------------------------------------------------*\ + ! Check if the global number of tiles is invalid. If true, ! + ! issue a warning and return to the function caller. ! + \*--------------------------------------------------------*/ + if(((double)control->numTilesX * control->numTilesY * + control->numTilesZ * control->numTilesTS) > 0xFFFFFFFFFFFFFFFF) + { + fprintf(stderr,"o==========================================================o\n"\ + "| WARNING: Invalid value |\n"\ + "| |\n"\ + "| The number of tiles exceeds its maxmum |\n"\ + "| allowable value. Please adjust all tile |\n"\ + "| dimension so that the number of tiles |\n"\ + "| falls within the range of: |\n"\ + "| |\n"\ + "| Number of Tiles < 2^64 |\n"\ + "| |\n"\ + "o==========================================================o\n"); + return; + } + } + else if(bwc_tile_numbof) + { + /*--------------------------------------------------------*\ + ! Check if the specified global number of tile sizes is ! + ! invalid. If true, issue a warning and return to the ! + ! function caller. ! + \*--------------------------------------------------------*/ + if(((double)tilesX * tilesY * tilesZ * tilesTS) > 0xFFFFFFFFFFFFFFFF) + { + fprintf(stderr,"o==========================================================o\n"\ + "| WARNING: Invalid value |\n"\ + "| |\n"\ + "| The number of tiles exceeds its maxmum |\n"\ + "| allowable value of: |\n"\ + "| |\n"\ + "| Number of Tiles < 2^64 |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + return; + } + + /*--------------------------------------------------------*\ + ! Amend the tile size in the bwc_field structure according ! + ! to the specified global number of tiles. ! + \*--------------------------------------------------------*/ + 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 global number of tiles is invalid. If true, ! + ! issue a warning and return to the function caller. ! + \*--------------------------------------------------------*/ + 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 |\n"\ + "| a value that falls outside of its valid |\n"\ + "| range. Please verify that the number of |\n"\ + "| tiles for all dimensions are set so |\n"\ + "| that the corresponding tile sizes fall |\n"\ + "| within the range of: |\n"\ + "| |\n"\ + "| 16 ≤ Tile_Size_Xi ≤ Grid_Points_Xi |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + return; + } + + /*--------------------------------------------------------*\ + ! Reevaluate the global number of tiles. ! + \*--------------------------------------------------------*/ + control->numTilesX = (uint64)ceil(((float)info->nX / control->tileSizeX)); + control->numTilesY = (uint64)ceil(((float)info->nY / control->tileSizeY)); + control->numTilesZ = (uint64)ceil(((float)info->nZ / control->tileSizeZ)); + control->numTilesTS = (uint16)ceil(((float)info->nTS/ control->tileSizeTS)); + + control->numTiles = control->numTilesX * control->numTilesY * + control->numTilesZ * control->numTilesTS; + } + + /*--------------------------------------------------------*\ + ! Record the setting in the CSsgc variable. ! + \*--------------------------------------------------------*/ + control->CSsgc |= (0x01 << 0); +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the wavelet kernels in the bwc_field structure according to ! +! the specified values. Dimensions for which no wavelet kernels have been ! +! specified are set to their respective standard values. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! KernelX, -Y, -Z, -TS bwc_dwt_filter - Wavelet kernels used for spatial ! +! and temporal decomposition. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 29.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +bwc_set_kernels(bwc_field *const field, + bwc_dwt_filter const KernelX, + bwc_dwt_filter const KernelY, + bwc_dwt_filter const KernelZ, + bwc_dwt_filter const KernelTS) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Amend the wavelet kernels in the bwc_field structure ac- ! + ! cording to the specified values and record the settings ! + ! in the CSsgc variable. ! + \*--------------------------------------------------------*/ + 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; + + control->CSsgc |= (0x01 << 1); +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the decomposition levels in the bwc_field structure ! +! according to the specified values. For all invalid dimensions (n = 1) the number ! +! of decomposition levels is automatically set to 0. All other dimensions are, as ! +! long as the specified value does not exceed the maximum number of possible ! +! decompositions, set accordingly. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! numDecompX,-Y,-Z,-TS unsigned int(8 bit) - Number of spatial and temporal ! +! wavelet decomposition levels ! +! used during compression. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 29.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +bwc_set_decomp(bwc_field *const field, + uint8 const numDecompX, + uint8 const numDecompY, + uint8 const numDecompZ, + uint8 const numDecompTS) +{ + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uint8 levelsX, levelsY; + uint8 levelsZ, levelsTS; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + /*--------------------------------------------------------*\ + ! Check if the decomposition levels have invalid values. ! + ! If true, issue a warning and return to the fun. caller. ! + \*--------------------------------------------------------*/ + if((control->numDecompX > 63) || + (control->numDecompY > 63) || + (control->numDecompZ > 63) || + (control->numDecompTS > 31)) + { + fprintf(stderr, "o==========================================================o\n"\ + "| WARNING: Invalid value |\n"\ + "| |\n"\ + "| The maximum acceptable decomposition |\n"\ + "| level is 63 for all spatial and 31 for |\n"\ + "| the temporal dimensions. |\n"\ + "| |\n"\ + "o==========================================================o\n"); + return; + } + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = &field->info; + + /*--------------------------------------------------------*\ + ! Calculate the possible number of subband levels for all ! + ! spatial and temporal dimensions and set the decomposi- ! + ! tion levels accordingly. ! + \*--------------------------------------------------------*/ + levelsX = log(info->nX) /log(2); + levelsY = log(info->nY) /log(2); + levelsZ = log(info->nZ) /log(2); + levelsTS = log(info->nTS)/log(2); + + control->numDecompX = (info->nX >> 1) ? ((numDecompX < levelsX) ? numDecompX : levelsX) : 0; + control->numDecompY = (info->nY >> 1) ? ((numDecompY < levelsY) ? numDecompY : levelsY) : 0; + control->numDecompZ = (info->nZ >> 1) ? ((numDecompZ < levelsZ) ? numDecompZ : levelsZ) : 0; + control->numDecompTS = (info->nTS >> 1) ? ((numDecompTS < levelsTS) ? numDecompTS : levelsTS) : 0; + + /*--------------------------------------------------------*\ + ! Calculate the overall number of decomposition levels and ! + ! record the settings in the CSsgc variable. ! + \*--------------------------------------------------------*/ + control->numDecomp = MAX(control->numDecompX, + MAX(control->numDecompY, + MAX(control->numDecompZ, control->numDecompTS))); + + control->CSsgc |= (0x01 << 2); +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the precinct size in the bwc_field structure acccording to ! +! the specified values. For all invalid dimensions (n = 1) the precinct size is ! +! automatically set to 0. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! pX,-Y,-Z,-TS unsigned int(8 bit) - Spatial and temporal precinct ! +! dimensions in log2 format. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 15.05.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 29.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +bwc_set_precincts(bwc_field *const field, + uint8 const pX, + uint8 const pY, + uint8 const pZ, + uint8 const pTS) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = &field->info; + + /*--------------------------------------------------------*\ + ! Check if the precinct sizes have invalid values. If ! + ! true, issue a warning and return to the function caller. ! + \*--------------------------------------------------------*/ + if((control->precSizeX > 15) || + (control->precSizeY > 15) || + (control->precSizeZ > 15) || + (control->precSizeTS > 15)) + { + fprintf(stderr, "o==========================================================o\n"\ + "| WARNING: Invalid value |\n"\ + "| |\n"\ + "| The maximum allowable precinct size is |\n"\ + "| 2^15. |\n"\ + "| |\n"\ + "o==========================================================o\n"); + + return; + } + + /*--------------------------------------------------------*\ + ! Amend the precinct size in the bwc_field structure ac- ! + ! cording to the specified values and record the settings ! + ! in the CSsgc variable. ! + \*--------------------------------------------------------*/ + 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; + + control->CSsgc |= (0x01 << 3); +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the codeblock size in the bwc_field structure acccording to ! +! the specified values. For all invalid dimensions (n = 1) the codeblock size is ! +! automatically set to 0. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! cbX, -Y, -Z, -TS unsigned int(8 bit) - Spatial and temporal codeblock ! +! dimensions in log2 format. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 29.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +bwc_set_codeblocks(bwc_field *const field, + uint8 const cbX, + uint8 const cbY, + uint8 const cbZ, + uint8 const cbTS) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = &field->info; + + /*--------------------------------------------------------*\ + ! Check if the codeblock sizes have invalid values. If ! + ! true, issue a warning and return to the function caller. ! + \*--------------------------------------------------------*/ + if(((control->cbX + control->cbY + control->cbZ + control->cbTS) < 4) || + ((control->cbX + control->cbY + control->cbZ + control->cbTS) > 20) || + (control->cbX > 10) || + (control->cbY > 10) || + (control->cbZ > 10) || + (control->cbTS > 10)) + { + fprintf(stderr, "o==========================================================o\n"\ + "| WARNING: Invalid value |\n"\ + "| |\n"\ + "| The maximum acceptable codeblock size |\n"\ + "| is 2^20 with a maximum allowable num- |\n"\ + "| ber of datapoints in each dimension of |\n"\ + "| 2^10. The smallest valid codeblock |\n"\ + "| size is 2^4. |\n"\ + "| |\n"\ + "o==========================================================o\n"); + return; + } + + /*--------------------------------------------------------*\ + ! Amend the codeblock size in the bwc_field structure ac- ! + ! cording to the specified values and record the settings ! + ! in the CSsgc variable. ! + \*--------------------------------------------------------*/ + 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; + + control->CSsgc |= (0x01 << 4); +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the progression order in the bwc_field structure according ! +! to the specified value. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! progression bwc_prog_ord - Progression order used to pack ! +! the codestream. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 29.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +bwc_set_progression(bwc_field *const field, + bwc_prog_ord const progression) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(progression == bwc_prog_LRCP); + + /*--------------------------------------------------------*\ + ! Amend the progression order in the bwc_field structure ! + ! according to the specified value and record the setting ! + ! in the CSsgc variable. ! + \*--------------------------------------------------------*/ + field->control.progression = progression; + field->control.CSsgc |= (0x01 << 5); +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! 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* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 13.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 29.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +bwc_set_error_resilience(bwc_field *const field) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Set the error resilience flag in the bwc_field structure ! + ! and record the setting in the CSsgc variable. ! + \*--------------------------------------------------------*/ + field->control.resilience ^= 0x01; + field->control.CSsgc ^= (0x01 << 6); +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function amends the quantization style in the bwc_field structure according ! +! to the user specified value. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! quantization_style bwc_quant_st - Quantization style used during ! +! compression. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 29.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +bwc_set_quant_style(bwc_field *const field, + bwc_quant_st const quantization_style) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert((quantization_style == bwc_qt_derived) || + (quantization_style == bwc_qt_none)); + + /*--------------------------------------------------------*\ + ! Amend the quantization style in the bwc_field structure ! + ! according to the specified value and record the setting ! + ! in the CSsgc variable. ! + \*--------------------------------------------------------*/ + field->control.quantization_style = quantization_style; + field->control.CSsgc |= (0x01 << 7); +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! 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* - Codec control structure. ! +! ! +! Qm unsigned int(8 bit) - Q number formate range. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 29.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +bwc_set_qm(bwc_field *const field, + uint8 const Qm) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Check if the Q number formate range is invalid. If true, ! + ! issue a warning and return to the function caller. ! + \*--------------------------------------------------------*/ + if((int8)(PREC_BIT - Qm) < 2) + { + fprintf(stderr, "o==========================================================o\n"\ + "| WARNING: Invalid value |\n"\ + "| |\n"\ + "| The specified Q number formate range |\n"\ + "| is larger than the permitted: |\n"\ + "| |\n"\ + "| %d bits |\n"\ + "| |\n"\ + "o==========================================================o\n",PREC_BIT - 1); + } + + /*--------------------------------------------------------*\ + ! Amend the Q number formate range in the bwc_field struc- ! + ! ture according to the specified values and record the ! + ! settings in the CSsgc variable. ! + \*--------------------------------------------------------*/ + field->control.Qm = Qm; + field->control.CSsgc |= (0x01 << 8); +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! 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* - Codec control structure. ! +! ! +! delta double - Quantization step size used ! +! during compression. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 16.04.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 18.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +bwc_set_quant_step_size(bwc_field *const field, + double delta) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables 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 << 9); +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to set the maximum number of OpenMP threads used during ! +! (de)compression. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! nThreads unsigned int(8 bit) - Number of OpenMP threads. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 07.08.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 22.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +#if defined(_OPENMP) + void + bwc_set_nThreads(bwc_field *const field, + uint8 const nThreads) + { + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + field->control.numThreads = nThreads; + } +#endif + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function sets the memory that can be allocated by the codec. If the limit ! +! is smaller than the amount of memory required to process at least 1 tile, the ! +! code will try to (de-)compress the dataset 1 tile at a time. If allocation ! +! fails, the codec will set an error flag in the field structure and terminate ! +! (de-)compression. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! limit unsigned int(64 bit) - String defining the memory ! +! lim it for (de-)compression. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 14.06.2020 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +bwc_set_memory_limit(bwc_field *const field, + char *const limit) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 multiplier; + uint64 tmp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(limit); + + /*--------------------------------------------------------*\ + ! Exctract the memory limit and byte multiplier from the ! + ! user supplied string. ! + \*--------------------------------------------------------*/ + sscanf(limit, "%ld%*[^0123456789]", &tmp); + + if((strchr(limit, 'k') != NULL) || + (strchr(limit, 'K') != NULL)) + { + multiplier = 1024; + } + else if((strchr(limit, 'm') != NULL) || + (strchr(limit, 'M') != NULL)) + { + multiplier = (uint64)pow(1024,2); + } + else if((strchr(limit, 'g') != NULL) || + (strchr(limit, 'G') != NULL)) + { + multiplier = (uint64)pow(1024,3); + } + else if((strchr(limit, 't') != NULL) || + (strchr(limit, 'T') != NULL)) + { + multiplier = (uint64)pow(1024,4); + } + + /*--------------------------------------------------------*\ + ! Calculate and store the memory limit in the field struc- ! + ! ture. ! + \*--------------------------------------------------------*/ + field->memory.limit = (uint64)tmp * multiplier; +} \ No newline at end of file diff --git a/src/library/libbwc.c b/src/library/libbwc.c index 0f321af..9bffa25 100755 --- a/src/library/libbwc.c +++ b/src/library/libbwc.c @@ -1,93 +1,51 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ - -/************************************************************************************************************\ -|| _ _ _ ____ _ _ _ ___ ____ || -|| | |\ | | | | | | \ |___ || -|| | | \| |___ |___ |__| |__/ |___ || -|| || -\************************************************************************************************************/ +/*====================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| Big Whoop is a compression codec for the lossy compression of IEEE 754 floating || +|| point arrays defined on curvelinear compute grids. || +|| || +|| ---------------------------------------------------------------------------------------------------------------- || +|| || +|| 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. || +|| || +\*====================================================================================================================*/ +/**********************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\**********************************************************************************************************************/ #include #include #include @@ -99,4502 +57,1635 @@ #include "bitstream.h" #include "constants.h" +#include "field.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; - } +#ifdef BWC_EAS3 + #include "eas3.h" #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) +/**********************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! 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* - Codec control structure. ! +! ! +! tileID unsigned int(64 bit) - Tile Index. ! +! ! +! parID unsigned int(16 bit) - Parameter Index ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 22.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 27.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Redefined for streaming ! +! functionality. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static uchar +fill_buffer(bwc_field *const field, + uint64 const tileID, + uint16 const parID) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int8 l; - size_t size; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 count, idx; + uint64 limit; - /*-----------------------*\ - ! DEFINE FLOAT VARIABLES: ! - \*-----------------------*/ - float buf_f; + uint64 memory_usage; + uint64 memory_limit; - /*-----------------------*\ - ! DEFINE CHAR VARIABLES: ! - \*-----------------------*/ - char *token, *ptr; + uint64 maxTileParamSize; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_gl_ctrl *control; + uint64 numTiles; + + uint64 width, height; + uint64 depth, dt; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(field); + uint64 sampX, sampY; + uint64 sampZ, sampTS; - /*--------------------------------------------------------*\ - ! 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; - } + uint64 t; - /*--------------------------------------------------------*\ - ! 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); + uint64 w, x, y, z; - if(token) - { - for(control->nLayers = 0; token; token = strtok_r(NULL, "-, ", &ptr)) - { - buf_f = strtof(token, NULL); + uint16 p; - 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; - } + uint8 parPrec; - if(((int8)size - control->nLayers) == 0) - { - size += 10; - control->bitrate = realloc(control->bitrate, size * sizeof(float)); - } + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + bwc_float *dest; + bwc_float *working_buffer; - 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; - } - } - } - } + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_inf *info; + + bwc_tile_inf *tile_info; + + bwc_parameter *parameter; + bwc_param_ctrl *param_control; + bwc_param_inf *param_info; + + bwc_packed_stream *tmp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(parID < field->info.numParams); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + info = &field->info; + + tile_info = field->setup.tile.info; + + parameter = &field->setup.tile.parameter[parID]; + param_control = ¶meter->control; + param_info = ¶meter->info; + + /*--------------------------------------------------------*\ + ! Check that the bwc_field structure is set to read from ! + ! a numerical dataset. ! + \*--------------------------------------------------------*/ + if((field->data.flag & DATA_IN) == 0) + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Invalid read |\n"\ + "| |\n"\ + "| The current bwc_field structure is not set |\n"\ + "| to read from a numerical dataset. |\n"\ + "| |\n"\ + "o##########################################################o\n"); + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Check wether the dataset is set to be streamed. ! + \*--------------------------------------------------------*/ + if((field->data.flag & DATA_STR) == 0) + { + /*--------------------------------------------------------*\ + ! Make sure that the data stream corresponds to the cor- ! + ! rect parameter ID and contains a valid memory chunk. If ! + ! true, safe the working buffer address to a temp variable.! + \*--------------------------------------------------------*/ + if((field->data.body[parID].param != parID) && + (field->data.body[parID].memory == NULL)) + { + // invalid paramter ID + fprintf(stderr, PARERROR); + return EXIT_FAILURE; + } else { - control->bitrate[0] = PREC_BIT + 1; - control->nLayers = 1; + working_buffer = (bwc_float*)field->setup.working_buffer.memory; } - } + /*--------------------------------------------------------*\ + ! Calculate the width, height, depth and dt as well as the ! + ! sample values of the current tile parameter. ! + \*--------------------------------------------------------*/ + parPrec = param_info->precision; + + 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; - control->bitrate = realloc(control->bitrate, control->nLayers * sizeof(float)); + sampX = 1 << param_control->sampX; + sampY = 1 << param_control->sampY; + sampZ = 1 << param_control->sampZ; + sampTS = 1 << param_control->sampTS; - /*--------------------------------------------------------*\ - ! Create the field structure used to compress a floating ! - ! point array defined by the bwc_initialize function. ! - \*--------------------------------------------------------*/ - if(create_field(field)) - { - return 1; - } + /*--------------------------------------------------------*\ + ! Check if the parameter is single or double precision and ! + ! proceed accordingly. ! + \*--------------------------------------------------------*/ + if(parPrec == 8) + { + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + double *src, *tmp; + + /*--------------------------------------------------------*\ + ! Cast the data stream memory block to a double pointer, ! + ! iterate over all columns in the tile paramter and load ! + ! them into the working buffer. ! + \*--------------------------------------------------------*/ + tmp = (double*)field->data.body[parID].memory; - /*--------------------------------------------------------*\ - ! Create the main header for the compressed codestream and ! - ! save the memory handle in the field structure. ! - \*--------------------------------------------------------*/ - if(assemble_main_header(field)) - { - return 1; - } + #if defined(_OPENMP) + #pragma omp parallel for collapse(3) private(dest, src, w, 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 the ! + ! next columns in the working buffer and data arrays. ! + \*--------------------------------------------------------*/ + src = &tmp[tile_info->X0 + info->nX * + (tile_info->Y0 + y * sampY + info->nY * + (tile_info->Z0 + z * sampZ + info->nZ * + t * sampTS))]; - return 0; + dest = &working_buffer[(uint64) width * (y + height * (z + depth * t))]; + + /*--------------------------------------------------------*\ + ! Loup through the temporary buffer, convert the data sam- ! + ! ples to the encoder precision and store them in the wor- ! + ! king buffer. ! + \*--------------------------------------------------------*/ + for(w = 0, x = 0; w < width; ++w, x += sampX) + { + dest[w] = (bwc_float)src[x]; + } + } + } + } + } + else if(parPrec == 4) + { + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + float *src, *tmp; + + /*--------------------------------------------------------*\ + ! Cast the data stream memory block to a float pointer, ! + ! iterate over all columns in the tile paramter and load ! + ! them into the working buffer. ! + \*--------------------------------------------------------*/ + tmp = (float*)field->data.body[parID].memory; + + #if defined(_OPENMP) + #pragma omp parallel for collapse(3) private(dest, src, w, 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 the ! + ! next columns in the working buffer and data arrays. ! + \*--------------------------------------------------------*/ + src = &tmp[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))]; + + /*--------------------------------------------------------*\ + ! Loup through the column, convert the data samples to the ! + ! encoder precision and store them in the working buffer. ! + \*--------------------------------------------------------*/ + for(w = 0, x = 0; w < width; ++w, x += sampX) + { + dest[w] = (bwc_float)src[x]; + } + } + } + } + } + } + else + { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + limit = field->data.limit; + count = field->data.count; + idx = field->data.idx; + + /*--------------------------------------------------------*\ + ! If no new tile paramters are available load the next set ! + ! into memory. ! + \*--------------------------------------------------------*/ + if(idx == count) + { + /*--------------------------------------------------------*\ + ! Initialize the data counter, parameter and tile IDs and ! + ! memory usage needed for the streaming operations. ! + \*--------------------------------------------------------*/ + count = + field->data.count = 0; + + idx = + field->data.idx = 0; + + t = tileID; + p = parID; + + maxTileParamSize = 0; + numTiles = field->control.numTiles; + + memory_limit = field->memory.limit; + memory_usage = field->memory.usage.data + + field->memory.usage.setup + + field->memory.usage.stat; + + /*--------------------------------------------------------*\ + ! Load the next tile parameters into memory as long as the ! + ! memory usage does not exceed the user defined limit. ! + \*--------------------------------------------------------*/ + do + { + /*--------------------------------------------------------*\ + ! Reallocate the packed stream array if the number of tile ! + ! parameters that can be ingested exceeds the number of al-! + ! located streams. ! + \*--------------------------------------------------------*/ + if(count == limit) + { + limit *= 2; + tmp = realloc(field->data.body, limit * sizeof(bwc_packed_stream)); + if(tmp == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + else + { + field->data.body = tmp; + field->memory.usage.data += (field->data.limit - limit) * sizeof(bwc_packed_stream); + + for(idx = count; idx < limit; ++idx) + { + memset(&field->data.body[idx], 0, sizeof(bwc_packed_stream)); + } + + field->data.body = tmp; + field->data.limit = limit; + + idx = 0; + } + } + + /*--------------------------------------------------------*\ + ! Ingest the next tile parameter and update the max. tile ! + ! param. size used to evaluate the memory usage. ! + \*--------------------------------------------------------*/ + if(field->data.IO(field, count, t, p)) + { + return EXIT_FAILURE; + } + maxTileParamSize = MAX(field->data.body[count].size, maxTileParamSize); + + /*--------------------------------------------------------*\ + ! Advance to the next data stream and, if all parameters ! + ! have been ingested, the next tile. ! + \*--------------------------------------------------------*/ + count++; + + if(++p == info->numParams) + { + p = 0; + t++; + } + } while ((memory_limit > (memory_usage + field->memory.usage.data + (2 * maxTileParamSize))) || + (t < numTiles)); + } + + /*--------------------------------------------------------*\ + ! Make sure that the next data block in the packed stream ! + ! data array has the appropriate tile and param ID and ! + ! link the tile paramter information to the working buff. ! + \*--------------------------------------------------------*/ + if((field->data.body[idx].tile == tileID) && + (field->data.body[idx].param == parID)) + { + field->setup.working_buffer.access = + field->setup.working_buffer.memory = field->data.body[idx].memory; + + field->setup.working_buffer.size = field->data.body[idx].size; + } + else + { + // invalid paramter ID + fprintf(stderr, PARERROR); + return EXIT_FAILURE; + } + } + /*--------------------------------------------------------*\ + ! Associate the working buffer with the appropriate param- ! + ! eter and return to the function caller. ! + \*--------------------------------------------------------*/ + field->setup.tile.parameter[parID].data = (bwc_float*)field->setup.working_buffer.memory; + + return EXIT_SUCCESS; } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to flush the working buffer to the flow field data memory ! +! block. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! working_buffer bwc_float* - Working buffer. ! +! ! +! parID unsigned int(16 bit) - Parameter Index ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 22.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 27.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Redefined for streaming ! +! functionality. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +// uchar +// flush_buffer(bwc_field *const field, +// uint64 const tileID, +// uint16 const parID) +// { +// /*-----------------------*\ +// ! DEFINE INT VARIABLES: ! +// \*-----------------------*/ +// uint64 count, idx; + +// uint64 width, height; +// uint64 depth, dt; + +// uint64 parSize; + +// uint64 sampX, sampY; +// uint64 sampZ, sampTS; + +// uint64 t; + +// uint64 w, x, y, z; + +// uint16 p; + +// uint8 parPrec; + +// /*-----------------------*\ +// ! DEFINE REAL VARIABLES: ! +// \*-----------------------*/ +// bwc_float *src; +// bwc_float *working_buffer; + +// /*-----------------------*\ +// ! DEFINE STRUCTS: ! +// \*-----------------------*/ +// bwc_gl_inf *info; + +// bwc_tile_inf *tile_info; + +// bwc_parameter *parameter; +// bwc_param_ctrl *param_control; +// bwc_param_inf *param_info; + +// bwc_packed_stream *tmp; + +// /*-----------------------*\ +// ! DEFINE ASSERTIONS: ! +// \*-----------------------*/ +// assert(field); +// assert(parID < field->info.numParams); + +// /*--------------------------------------------------------*\ +// ! Save frequently used variables/structures to temporary ! +// ! variables to make the code more readable. ! +// \*--------------------------------------------------------*/ +// info = &field->info; + +// tile_info = &field->setup.tile.info; + +// parameter = &field->setup.tile.parameter[parID]; +// param_control = ¶meter->control; +// param_info = ¶meter->info; + +// /*--------------------------------------------------------*\ +// ! Check that the bwc_field structure is set to write to a ! +// ! numerical dataset. ! +// \*--------------------------------------------------------*/ +// if((field->data.flag & DATA_OUT) == 0) +// { +// fprintf(stderr, "o##########################################################o\n"\ +// "| ERROR: Invalid write |\n"\ +// "| |\n"\ +// "| The current bwc_field structure is not set |\n"\ +// "| to write to a numerical dataset. |\n"\ +// "| |\n"\ +// "o##########################################################o\n"); +// return EXIT_FAILURE; +// } +// /*--------------------------------------------------------*\ +// ! Check wether the dataset is set to be streamed. ! +// \*--------------------------------------------------------*/ +// if((field->data.flag & DATA_STR) == 0) +// { +// /*--------------------------------------------------------*\ +// ! Make sure that the data stream corresponds to the cor- ! +// ! rect parameter ID and contains a valid memory chunk. If ! +// ! true, safe the working buffer address to a temp variable.! +// \*--------------------------------------------------------*/ +// if((field->data.body[parID].param != parID) && +// (field->data.body[parID].memory == NULL)) +// { +// // invalid paramter ID +// fprintf(stderr, PARERROR); +// return EXIT_FAILURE; +// } +// else +// { +// working_buffer = (bwc_float*)field->data.body[parID].memory; +// } +// /*--------------------------------------------------------*\ +// ! Calculate the width, height, depth and dt as well as the ! +// ! sample values of the current tile parameter. ! +// \*--------------------------------------------------------*/ +// parPrec = param_info->precision; + +// 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; + +// parSize = width * height * depth * dt * parPrec; + +// /*--------------------------------------------------------*\ +// ! Check if the parameter is single or double precision and ! +// ! proceed accordingly. ! +// \*--------------------------------------------------------*/ +// if(parPrec == 8) +// { +// /*-----------------------*\ +// ! DEFINE FLOAT VARIABLES: ! +// \*-----------------------*/ +// double *dest, *tmp; + +// /*--------------------------------------------------------*\ +// ! Cast the data stream memory block to a double pointer, ! +// ! iterate over all columns in the tile paramter and load ! +// ! them into the working buffer. ! +// \*--------------------------------------------------------*/ +// tmp = (double*)field->data.body[parID].memory; + +// #if defined(_OPENMP) +// #pragma omp parallel for collapse(3) private(dest, src, w, 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 the ! +// ! next columns in the working buffer and data arrays. ! +// \*--------------------------------------------------------*/ +// dest = &tmp[param_info->X0 + info->nX * +// (param_info->Y0 + y + info->nY * +// (param_info->Z0 + z + info->nZ * t ))]; + +// src = &working_buffer[(uint64) width * (y + height * (z + depth * t))]; + +// /*--------------------------------------------------------*\ +// ! Loup through the column, convert the data samples to dou-! +// ! ble precision and store them in the parameter structure. ! +// \*--------------------------------------------------------*/ +// for(x = 0; x < width; ++x) +// { +// dest[x] = (double)src[x]; +// } +// } +// } +// } +// } +// else if(parPrec == 4) +// { +// /*-----------------------*\ +// ! DEFINE FLOAT VARIABLES: ! +// \*-----------------------*/ +// float *dest, *tmp; + +// /*--------------------------------------------------------*\ +// ! Cast the data stream memory block to a float pointer, ! +// ! iterate over all columns in the tile paramter and load ! +// ! them into the working buffer. ! +// \*--------------------------------------------------------*/ +// tmp = (float*)field->data.body[parID].memory; + +// #if defined(_OPENMP) +// #pragma omp parallel for collapse(3) private(dest, src, w, 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 the ! +// ! next columns in the working buffer and data arrays. ! +// \*--------------------------------------------------------*/ +// src = &tmp[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))]; + +// /*--------------------------------------------------------*\ +// ! Loup through the column, convert the data samples to sin-! +// ! gle precision and store them in the parameter structure. ! +// \*--------------------------------------------------------*/ +// for(x = 0; x < width; ++x) +// { +// dest[x] = (float)src[x]; +// } +// } +// } +// } +// } +// } +// else +// { +// /*--------------------------------------------------------*\ +// ! Save frequently used variables/structures to temporary ! +// ! variables to make the code more readable. ! +// \*--------------------------------------------------------*/ +// count = field->data.count; +// idx = field->data.idx; + +// /*--------------------------------------------------------*\ +// ! If no new tile paramters are available clear the corre- ! +// ! sponding packed stream array and load additional data ! +// ! blocks into memory. ! +// \*--------------------------------------------------------*/ +// if((field->memory.usage + field->data.body[idx++].size) < field->memory.limit) +// if(idx >= count) +// { +// for(idx = 0; idx < count; ++idx) +// { +// if(field->data.IO(field, idx, t, p)) +// { +// return EXIT_FAILURE; +// } + +// field->memory.usage -= field->data.body[idx].size; +// free(field->data.body[idx].memory); + +// field->data.body[idx].tile = +// field->data.body[idx].param = +// field->data.body[idx].size = 0; + +// field->data.body[idx].access = +// field->data.body[idx].memory = NULL; +// } + +// idx = 0; +// t = tileID; +// p = parID; + +// do +// { +// if(idx == count) +// { +// count += 10; +// tmp = realloc(field->data.body, count); +// if(tmp != NULL) +// { +// field->data.body = tmp; +// field->data.count = count; + +// field->memory.usage += 10 * sizeof(bwc_packed_stream); +// } +// } + +// if(++p == info->numParams) +// { +// p = 0; +// t++; +// } +// } while ((field->memory.usage + field->data.body[idx++].size) < field->memory.limit); +// } + +// /*--------------------------------------------------------*\ +// ! Make sure that the next data block in the packed stream ! +// ! data array has the appropriate tile and param ID and ! +// ! link the tile paramter information to the working buff. ! +// \*--------------------------------------------------------*/ +// if((field->data.body[idx].tile == tileID) && +// (field->data.body[idx].param == parID)) +// { +// field->setup.working_buffer.access = +// field->setup.working_buffer.memory = field->data.body[idx].memory; + +// field->setup.working_buffer.size = field->data.body[idx].size; + +// field->data.idx++; +// } +// else +// { +// // invalid paramter ID +// fprintf(stderr, PARERROR); +// return EXIT_FAILURE; +// } +// } +// return EXIT_SUCCESS; +// } + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! 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 ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! parID unsigned int(16 bit) - Parameter Index ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 24.08.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 27.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static void +normalize_param(bwc_field *const field, + uint16 const parID) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + bwc_raw shift; + + uint64 param_size; + uint64 x; + + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + bwc_float alpha, beta; + bwc_float min, max; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_parameter *parameter; + bwc_sample *tmp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(parID < field->info.numParams); + assert(field->setup.tile.parameter[parID].data != NULL); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + parameter = &field->setup.tile.parameter[parID]; + tmp = (bwc_sample*)parameter->data; + + /*--------------------------------------------------------*\ + ! Calculate the size of the current tile parameter and in- ! + ! itialize the maximum and minimum parameter values. ! + \*--------------------------------------------------------*/ + param_size = (parameter->info.X1 - parameter->info.X0) * + (parameter->info.Y1 - parameter->info.Y0) * + (parameter->info.Z1 - parameter->info.Z0) * + (parameter->info.TS1 - parameter->info.TS0); + + max = -FLT_MAX; + min = FLT_MAX; + + /*--------------------------------------------------------*\ + ! Walk through the tile parameter data and update the min- ! + ! imum and maximum parameter values. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp parallel for reduction(max:max) reduction(min:min) + #endif + for(x = 0; x < param_size; ++x) + { + max = MAX(max, tmp[x].f); + min = MIN(min, tmp[x].f); + } + + /*--------------------------------------------------------*\ + ! Save the maximum and minimum parameter values in the cor-! + ! responding info structure. ! + \*--------------------------------------------------------*/ + parameter->info.max = max; + parameter->info.min = min; + + /*--------------------------------------------------------*\ + ! Evaluate the normalization constants and the paramter ! + ! used to shift the floating point number to the Q number ! + ! range. ! + \*--------------------------------------------------------*/ + shift = (uint64)field->control.Qm << PREC_MANTISSA; + + alpha = (max + min)/2.0f; + beta = 2.0f/(max - min); + + /*--------------------------------------------------------*\ + ! Walk through the tile parameter data and scale and nor- ! + ! malize the flow field values. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp parallel for + #endif + for(x = 0; x < param_size; ++x) + { + tmp[x].f = (bwc_float)(tmp[x].f - alpha) * beta; + + tmp[x].raw += (((tmp[x].raw & EXPONENT) == 0)&& + ((tmp[x].raw & MANTISSA) == 0)) ? 0 : shift; + } + + /*--------------------------------------------------------*\ + ! Save the normalization constants in the parameter con- ! + ! trol structure. ! + \*--------------------------------------------------------*/ + parameter->control.alpha = alpha; + parameter->control.beta = beta; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! 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 ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! parID unsigned int(16 bit) - Parameter Index ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 24.08.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 27.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static void +denormalize_param(bwc_field *const field, + uint16 const parID) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + bwc_raw shift; + + uint64 param_size; + uint64 x; + + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + bwc_float alpha, beta; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_parameter *parameter; + bwc_sample *tmp; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(parID < field->info.numParams); + assert(field->setup.tile.parameter[parID].data != NULL); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + parameter = &field->setup.tile.parameter[parID]; + tmp = (bwc_sample*)parameter->data; + + /*--------------------------------------------------------*\ + ! Calculate the size of the current tile parameter. ! + \*--------------------------------------------------------*/ + param_size = (parameter->info.X1 - parameter->info.X0) * + (parameter->info.Y1 - parameter->info.Y0) * + (parameter->info.Z1 - parameter->info.Z0) * + (parameter->info.TS1 - parameter->info.TS0); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + alpha = (parameter->info.max + parameter->info.min)/2.0f; + beta = (parameter->info.max - parameter->info.min)/2.0f; + + /*--------------------------------------------------------*\ + ! Shift the Q number range to the appropriate position for ! + ! the IEEE 754 floating point number. ! + \*--------------------------------------------------------*/ + shift = (uint64)field->control.Qm << PREC_MANTISSA; + + /*--------------------------------------------------------*\ + ! Walk through the tile parameter data and scale and de- ! + ! normalize the flow field values. ! + \*--------------------------------------------------------*/ + #if defined(_OPENMP) + #pragma omp parallel for + #endif + for(x = 0; x < param_size; ++x) + { + tmp[x].raw -= (((tmp[x].raw & EXPONENT) == 0) && + ((tmp[x].raw & MANTISSA) == 0)) ? 0 : shift; + + tmp[x].f = (bwc_float)(tmp[x].f * beta) + alpha; + } +} + +/**********************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function calls the appropriate initialization function for the file type ! +! supplied by the function caller if the file format is supported by the bwc ! +! library. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! filename char* - Name of file to be opened. ! +! ! +! mode char* - File operations mode. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 15.02.2020 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ uchar -bwc_compress(bwc_field *const field, bwc_data *const data) +bwc_open_file(bwc_field *const field, + char const *const filename, + char const *const mode) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 buff_size = 0; - uint64 i; - uint16 p; + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(filename); - /*-----------------------*\ - ! 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) + if(strstr(filename, ".bwc") != NULL) + { + //insert function here + return EXIT_SUCCESS; + } + #ifdef BWC_EAS3 + else if (strstr(filename, ".eas") != NULL) { - /*--------------------------------------------------------*\ - ! 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; + if(open_eas3(field, filename, mode) == EXIT_SUCCESS) + { + //invalid file operation + return EXIT_SUCCESS; + } } - /*--------------------------------------------------------*\ - ! 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 + #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; + fprintf(stderr, FRMERROR); + return EXIT_FAILURE; } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function calls, if the file format is supported, the appropriate function ! +! that loads a file into memory. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! filename char* - Name of file to be opened. ! +! ! +! mode char* - File operations mode. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 15.02.2020 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ uchar -bwc_decompress(bwc_field *const field, bwc_data *const data) +bwc_load_file(bwc_field *const field, + char const *const filename) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 buff_size; - uint64 single_size, double_size; - uint64 i; - uint16 p; + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(filename); - /*-----------------------*\ - ! 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(strstr(filename, ".bwc") != NULL) + { + //insert function here + return EXIT_SUCCESS; + } + #ifdef BWC_EAS3 + else if (strstr(filename, ".eas") != NULL) { - if(param->precision == 8) - { - double_size += param->size; - } - else if (param->precision == 4) - { - single_size += param->size; - } - - param = param -> next; + if(load_eas3(field, filename) == EXIT_SUCCESS) + { + //invalid file operation + return EXIT_SUCCESS; + } } - } + #endif - 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; - } + return EXIT_FAILURE; +} - /*--------------------------------------------------------*\ - ! Evaluate the working buffer size and allocate it accord- ! - ! ingly. ! - \*--------------------------------------------------------*/ - buff_size = control->tileSizeX * control->tileSizeY * - control->tileSizeZ * control->tileSizeTS; +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! - ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! rate_control char* - Array of up to 10 strings ! +! defining the quality layers. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 04.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! 15.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Adapted for streaming ! +! functionality. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +uchar +bwc_compress(bwc_field *const field, + char *const rate_control) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 t; + uint16 p; + int8 l; - working_buffer = calloc(buff_size, sizeof(bwc_sample)); - if(!working_buffer) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return 1; - } + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + double start, end; + float buff; - /*--------------------------------------------------------*\ - ! Walk through the tile structure and decompress the speci-! - ! fied data set. ! - \*--------------------------------------------------------*/ - for(i = 0; i < control->nTiles; ++i) - { + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char *token, *ptr; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Initialize the compression time measurement. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + field->meter.time.ttl = omp_get_wtime(); + #else + field->meter.time.ttl = (double)clock(); + #endif + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures 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->numThreads); + #endif + + /*--------------------------------------------------------*\ + ! Extract, sort and store the bitrates and evaluate the ! + ! number of quality layers. ! + \*--------------------------------------------------------*/ + if(rate_control == NULL) + { + control->bitrate[0] = PREC_BIT + 1; + control->numLayers = 1; + } + else + { + token = strtok_r(rate_control, "-, ", &ptr); + + if(token != NULL) + { + for(control->numLayers = 0; + control->numLayers < 10 && token; + token = strtok_r(NULL, "-, ", &ptr)) + { + buff = strtof(token, NULL); + + if(buff <= 0 || buff > 64) + { + fprintf(stderr, "o##########################################################o\n"\ + "| ERROR: Invalid value: %8.1f |\n"\ + "| |\n"\ + "| One of the specified bitrates is not |\n"\ + "| within the valid range of: |\n"\ + "| |\n"\ + "| 0 < Bitrate ≤ 64 |\n"\ + "| |\n"\ + "o##########################################################o\n", buff); + return EXIT_FAILURE; + } + + for(l = control->numLayers; l >= 0; --l) + { + if((l > 0) && (buff < control->bitrate[l - 1])) + { + control->bitrate[l] = control->bitrate[l - 1]; + } + else if ((l > 0) && (fabs(buff - control->bitrate[l - 1]) < 0.01f)) + { + for(; l < control->numLayers; ++l) + { + control->bitrate[l] = control->bitrate[l + 1]; + } + break; + } + else + { + control->bitrate[l] = buff; + control->numLayers++; + break; + } + } + } + } + else + { + control->bitrate[0] = PREC_BIT + 1; + control->numLayers = 1; + } + } + /*--------------------------------------------------------*\ + ! Initialize the field structure, discrete wavelet trans- ! + ! form energy gain look-up tables and codestream header. ! + \*--------------------------------------------------------*/ + field->setup.flag = SETUP_CMP; + + if(create_field(field) == EXIT_FAILURE) + { + return EXIT_FAILURE; + } + + /*--------------------------------------------------------*\ + ! Walk through the tile structure and compress the speci- ! + ! fied data set. ! + \*--------------------------------------------------------*/ + for(t = 0; t < control->numTiles; ++t) + { + printf("ping %ld\n", t); /*--------------------------------------------------------*\ - ! Save the tile structure in a temporary variable to make ! - ! the code more readable. ! + ! Adapt the field structure for the next tile. ! \*--------------------------------------------------------*/ - tile = &field->tile[i]; + if(adapt_tile(field, t)) + { + return EXIT_FAILURE; + } - 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) + for(p = 0; p < info->numParams; ++p) + { + /*--------------------------------------------------------*\ + ! Fill the working buffer with the flow field data for the ! + ! current tile parameter. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) start = omp_get_wtime(); - #else + #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(); + #endif + if(fill_buffer(field, t, p) == EXIT_FAILURE) + { + return EXIT_FAILURE; + } + #if defined (_OPENMP) + end = omp_get_wtime(); field->meter.time.cpy += end - start; - #else - end = (double)clock(); + #else + end = (double)clock(); field->meter.time.cpy += (end - start)/CLOCKS_PER_SEC; - #endif + #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, p); + #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 - /*--------------------------------------------------------*\ - ! Reset the working buffer memory block. ! - \*--------------------------------------------------------*/ - memset(working_buffer, 0, buff_size * sizeof(bwc_sample)); - parameter->data = NULL; - } - } + /*--------------------------------------------------------*\ + ! Perform the forward discrete wavelet transform. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + start = omp_get_wtime(); + #else + start = (double)clock(); + #endif + if(forward_wavelet_transform(field, p) == EXIT_FAILURE) + { + return EXIT_FAILURE; + } + #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 - /*--------------------------------------------------------*\ - ! Free the working buffer. ! - \*--------------------------------------------------------*/ - free(working_buffer); + /*--------------------------------------------------------*\ + ! Tier1 encode the current tile parameter. ! + \*--------------------------------------------------------*/ + #if defined (_OPENMP) + start = omp_get_wtime(); + #else + start = (double)clock(); + #endif + if(t1_encode(field, p)) + { + return EXIT_FAILURE; + } + #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 + } + // /*--------------------------------------------------------*\ + // ! Tier2 encode the current tile. ! + // \*--------------------------------------------------------*/ + // #if defined (_OPENMP) + // start = omp_get_wtime(); + // #else + // start = (double)clock(); + // #endif + // if(t2_encode(field)) + // { + // return EXIT_FAILURE; + // } + // #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 - /*--------------------------------------------------------*\ - ! 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 + /*--------------------------------------------------------*\ + ! Assemble compressed codestream. ! + \*--------------------------------------------------------*/ + // #if defined (_OPENMP) + // start = omp_get_wtime(); + // #else + // start = (double)clock(); + // #endif + // assemble_codestream(); + // #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 + } - return 0; -} \ No newline at end of file + /*--------------------------------------------------------*\ + ! 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 EXIT_FAILURE; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! - ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! rate_control char* - Array of up to 10 strings ! +! defining the quality layers. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 04.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! 15.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Adapted for streaming ! +! functionality. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +// uchar +// bwc_decompress(bwc_field *const field, +// uint8 const layer) +// { +// /*-----------------------*\ +// ! DEFINE INT VARIABLES: ! +// \*-----------------------*/ +// uint64 t; +// uint16 p; + +// /*-----------------------*\ +// ! DEFINE REAL VARIABLES: ! +// \*-----------------------*/ +// double start, end; + +// /*-----------------------*\ +// ! DEFINE STRUCTS: ! +// \*-----------------------*/ +// bwc_gl_ctrl *control; +// bwc_gl_inf *info; + +// bwc_tile *tile; + +// bwc_parameter *parameter; + +// /*-----------------------*\ +// ! DEFINE ASSERTIONS: ! +// \*-----------------------*/ +// assert(field); + +// /*--------------------------------------------------------*\ +// ! Initialize the decompression time measurement. ! +// \*--------------------------------------------------------*/ +// #if defined (_OPENMP) +// field->meter.time.ttl = omp_get_wtime(); +// #else +// field->meter.time.ttl = (double)clock(); +// #endif + +// /*--------------------------------------------------------*\ +// ! Save frequently used variables/structures 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->numThreads); +// #endif + +// /*--------------------------------------------------------*\ +// ! Initialize the field structure, discrete wavelet trans- ! +// ! form energy gain look-up tables and codestream header. ! +// \*--------------------------------------------------------*/ +// field->setup.flag = SETUP_CMP; + +// if(create_field(field) == EXIT_FAILURE) +// { +// return EXIT_FAILURE; +// } + +// /*--------------------------------------------------------*\ +// ! Walk through the tile structure and decompress the speci-! +// ! fied data set. ! +// \*--------------------------------------------------------*/ +// for(t = 0; t < control->numTiles; ++t) +// { +// /*--------------------------------------------------------*\ +// ! Adapt the field structure for the next tile. ! +// \*--------------------------------------------------------*/ +// if(adapt_tile(field, t)) +// { +// return EXIT_FAILURE; +// } + +// for(p = 0; p < info->numParams; ++p) +// { +// /*--------------------------------------------------------*\ +// ! Save frequently used variables/structures to temporary ! +// ! variables to make the code more readable. ! +// \*--------------------------------------------------------*/ +// parameter = &tile->parameter[p]; + +// /*--------------------------------------------------------*\ +// ! Tier1 decode the current tile parameter. ! +// \*--------------------------------------------------------*/ +// #if defined (_OPENMP) +// start = omp_get_wtime(); +// #else +// start = (double)clock(); +// #endif +// if(t1_decode(field, tile, parameter)) +// { +// return EXIT_FAILURE; +// } +// #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_wavelet_transform(field, parameter)) +// { +// return EXIT_FAILURE; +// } +// #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, p); +// #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, t, 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 +// } +// } +// /*--------------------------------------------------------*\ +// ! 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 EXIT_SUCCESS; +// } \ No newline at end of file diff --git a/src/library/mq.c b/src/library/mq.c index 41e1e1c..68462a3 100755 --- a/src/library/mq.c +++ b/src/library/mq.c @@ -1,75 +1,50 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ - -/************************************************************************************************************\ -|| _ _ _ ____ _ _ _ ___ ____ || -|| | |\ | | | | | | \ |___ || -|| | | \| |___ |___ |__| |__/ |___ || -|| || -\************************************************************************************************************/ +/*====================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| DESCRIPTION NEEDED. || +|| || +|| ---------------------------------------------------------------------------------------------------------------- || +|| || +|| 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. || +|| || +\*====================================================================================================================*/ +/**********************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\**********************************************************************************************************************/ #include #include #include @@ -77,20 +52,21 @@ #include "macros.h" #include "mq.h" +#include "tier1.h" #include "types.h" +/**********************************************************************************************************************\ +|| _ _ ____ ____ ____ ____ ____ || +|| |\/| |__| | |__/ | | [__ || +|| | | | | |___ | \ |__| ___] || +|| || +\**********************************************************************************************************************/ -/************************************************************************************************************\ -|| _ _ ____ ____ ____ ____ ____ || -|| |\/| |__| | |__/ | | [__ || -|| | | | | |___ | \ |__| ___] || -|| || -\************************************************************************************************************/ /*----------------------------------------------------------------------------------------------------------*\ ! DESCRIPTION: ! ! ------------ ! ! DESCRIPTION NEEDED ! ! ! -! Macros: ! +! MACROS: ! ! ------- ! ! Macro Description ! ! ----- ----------- ! @@ -101,50 +77,50 @@ ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 22.02.2019 Patrick Vogler B87D120 V 0.1.0 Macros created ! +! 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; \ - } \ - } \ +#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; \ + } \ + } \ } /*----------------------------------------------------------------------------------------------------------*\ @@ -152,7 +128,7 @@ ! ------------ ! ! DESCRIPTION NEEDED ! ! ! -! Macros: ! +! MACROS: ! ! ------- ! ! Macro Description ! ! ----- ----------- ! @@ -163,34 +139,34 @@ ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 22.02.2019 Patrick Vogler B87D120 V 0.1.0 Macros created ! +! 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++; \ - } \ - } \ +#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++; \ + } \ + } \ } /************************************************************************************************************\ @@ -212,7 +188,7 @@ ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! ! ! \*----------------------------------------------------------------------------------------------------------*/ static const bwc_context_state context_state[94] = @@ -318,7 +294,7 @@ static const bwc_context_state context_state[94] = || || \************************************************************************************************************/ /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void initialize_bit_encoder(void) ! +! FUNCTION NAME: void initialize_mq_encoder(void) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -342,64 +318,66 @@ static const bwc_context_state context_state[94] = ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 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) +initialize_mq_encoder(bwc_coder *const coder, + uint8 const numContexts) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint8 i; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint8 i; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_bit_coder *bitcoder; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_bit_coder *bitcoder; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(coder); - assert(coder->compressed); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + assert(coder->compressed); - coder->bitcoder = calloc(1, sizeof(bwc_bit_coder)); - if(!coder->bitcoder) - { + coder->bitcoder = calloc(1, sizeof(bwc_bit_coder)); + if(coder->bitcoder == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return 1; - } + return EXIT_FAILURE; + } - bitcoder = coder->bitcoder; + bitcoder = coder->bitcoder; - bitcoder->nContext = number_of_contexts; + bitcoder->nContext = numContexts; - bitcoder->b = coder->compressed; + bitcoder->b = coder->compressed; - bitcoder->context = calloc(bitcoder->nContext, sizeof(bwc_context_state*)); - if(!bitcoder->context) - { + bitcoder->context = calloc(bitcoder->nContext, sizeof(bwc_context_state*)); + if(bitcoder->context == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return 1; - } + free(coder->bitcoder); + return EXIT_FAILURE; + } - for(i = 0; i < number_of_contexts; ++i) - { + for(i = 0; i < numContexts; ++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->context[CONTEXT_SIG] = &context_state[ 4]; + bitcoder->context[CONTEXT_RUN] = &context_state[ 3]; + bitcoder->context[CONTEXT_UNI] = &context_state[46]; - return 0; + return EXIT_SUCCESS; } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void initialize_bit_encoder(void) ! +! FUNCTION NAME: void initialize_mq_encoder(void) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -423,52 +401,52 @@ initialize_bit_encoder(bwc_coder *const coder, const uint8 number_of_contexts) ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! ! ! \*----------------------------------------------------------------------------------------------------------*/ uchar -bit_encoder_next_run(bwc_bit_coder *const bitcoder) +mq_next_run(bwc_bit_coder *const bitcoder) { - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_coder_state *state; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(bitcoder); + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_state *state; - state = calloc(1, sizeof(bwc_coder_state)); - if(!state) - { + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(bitcoder); + + state = calloc(1, sizeof(bwc_coder_state)); + if(state == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return 1; - } + return EXIT_FAILURE; + } - if(bitcoder->state) - { + if(bitcoder->state != NULL) + { memcpy(state, bitcoder->state, sizeof(bwc_coder_state)); state->prev = bitcoder->state; bitcoder->state->next = state; bitcoder->state = state; - } - else - { + } + else + { bitcoder->state = state; bitcoder->state->b = bitcoder->b; state->A = 0x8000; state->t = 0x000C; state->L = -0x0001; - } - - return 0; + } + + return EXIT_SUCCESS; } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void initialize_bit_encoder(void) ! +! FUNCTION NAME: void initialize_mq_encoder(void) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -492,92 +470,94 @@ bit_encoder_next_run(bwc_bit_coder *const bitcoder) ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 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) +mq_bit_encode(bwc_bit_coder *const bitcoder, + uint8 const s, + uint8 const k) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint16 p; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(bitcoder); - - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_context_state const **context; - bwc_coder_state *state; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint16 p; - context = bitcoder->context; - state = bitcoder->state; + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(bitcoder); - p = context[k]->p; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_context_state const **context; + bwc_coder_state *state; - state->A -= p; + context = bitcoder->context; + state = bitcoder->state; - if(s == context[k]->sk) - { + p = context[k]->p; + + state->A -= p; + + if(s == context[k]->sk) + { if(state->A >= 0x8000) - { - state->C += p; - } + { + 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) + { + if(state->A < p) { - transfer_byte(state); + state->A = p; } - } while (state->A < 0x8000); - } - } - else - { + 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; - } + { + state->C += p; + } else - { - state->A = p; - } + { + 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); - } + { + 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) ! +! FUNCTION NAME: void initialize_mq_encoder(void) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -601,102 +581,102 @@ bit_encode(bwc_bit_coder *const bitcoder, const uint8 s, const uint8 k) ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! ! ! \*----------------------------------------------------------------------------------------------------------*/ void -bit_encoder_truncation_length_min(bwc_coder_state *const state) +mq_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 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; + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(state); - CrDec = state->T; - CArDec = state->T; + #ifdef BWC_SINGLE_PRECISION + CrFrac = (int32)state->C << state->t; + CArFrac = ((int32)state->A << state->t) + CrFrac; - CrDec += 0x01 & (CrFrac >> 27); - CArDec += 0x01 & (CArFrac >> 27); + CrDec = state->T; + CArDec = state->T; - CrFrac &= 0x7FFFFFF; - CArFrac &= 0x7FFFFFF; + CrDec += 0x01 & (CrFrac >> 27); + CArDec += 0x01 & (CArFrac >> 27); - s = 8; + CrFrac &= 0x7FFFFFF; + CArFrac &= 0x7FFFFFF; - while((CrDec > 0xff) || - (CArDec <= 0xff)) + s = 8; + + while((CrDec > 0xff) || + (CArDec <= 0xff)) { - buff = (state->L >= 0) ? (int32)state->b[state->L] : 0; - state->L++; + buff = (state->L >= 0) ? (int32)state->b[state->L] : 0; + state->L++; - CrDec -= buff << (8 - s); - CArDec -= buff << (8 - s); + CrDec -= buff << (8 - s); + CArDec -= buff << (8 - s); - CrDec <<= s; - CArDec <<= s; + CrDec <<= s; + CArDec <<= s; - CrDec += CrFrac >> (27 - s); - CArDec += CArFrac >> (27 - s); + CrDec += CrFrac >> (27 - s); + CArDec += CArFrac >> (27 - s); - CrFrac <<= s; - CArFrac <<= s; + CrFrac <<= s; + CArFrac <<= s; - CrFrac &= 0x7FFFFFF; - CArFrac &= 0x7FFFFFF; + CrFrac &= 0x7FFFFFF; + CArFrac &= 0x7FFFFFF; - s = (buff == 0xFF) ? 7 : 8; + 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; + #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)) + while(((Cr >> 27) > 0xff) || + ((CAr >> 27) <= 0xff)) { - buff = (state->L >= 0) ? (int64)state->b[state->L] : 0; - state->L++; + buff = (state->L >= 0) ? (int64)state->b[state->L] : 0; + state->L++; - Cr -= buff << (35 - s); - CAr -= buff << (35 - s); + Cr -= buff << (35 - s); + CAr -= buff << (35 - s); - Cr <<= s; - CAr <<= s; + Cr <<= s; + CAr <<= s; - s = (buff == 0xFF) ? 7 : 8; + s = (buff == 0xFF) ? 7 : 8; } - #endif + #endif - if(state->L > 0 && (state->b[state->L - 1] == 0xFF)) - { + 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)) - { + } + 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) ! +! FUNCTION NAME: void initialize_mq_encoder(void) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -720,67 +700,67 @@ bit_encoder_truncation_length_min(bwc_coder_state *const state) ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! ! ! \*----------------------------------------------------------------------------------------------------------*/ void -bit_encoder_termination(bwc_bit_coder *const bitcoder) +mq_termination(bwc_bit_coder *const bitcoder) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int8 n; - - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_coder_state buff; - bwc_coder_state *state; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int8 n; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(bitcoder); + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_state buff; + bwc_coder_state *state; - state = bitcoder->state; + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(bitcoder); - buff.A = state->A; - buff.C = state->C; - buff.L = state->L; - buff.T = state->T; - buff.t = state->t; + state = bitcoder->state; - n = 12 - state->t; - state->C <<= state->t; + buff.A = state->A; + buff.C = state->C; + buff.L = state->L; + buff.T = state->T; + buff.t = state->t; - while(n > 0) - { + n = 12 - state->t; + state->C <<= state->t; + + while(n > 0) + { transfer_byte(state); n -= state->t; state->C <<= state->t; - } - transfer_byte(state); + } + transfer_byte(state); - state->A = buff.A; - state->C = buff.C; - state->L = buff.L; - state->T = buff.T; - state->t = buff.t; + state->A = buff.A; + state->C = buff.C; + state->L = buff.L; + state->T = buff.T; + state->t = buff.t; - while(state->prev) - { + while(state->prev != NULL) + { state = state->prev; - } + } - while(state) - { - bit_encoder_truncation_length_min(state); + while(state != NULL) + { + mq_truncation_length_min(state); state = state->next; - } + } } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void initialize_bit_encoder(void) ! +! FUNCTION NAME: void initialize_mq_encoder(void) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -804,39 +784,43 @@ bit_encoder_termination(bwc_bit_coder *const bitcoder) ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! ! ! \*----------------------------------------------------------------------------------------------------------*/ void -free_bit_encoder(bwc_coder *const coder) +free_mq_encoder(bwc_coder *const coder) { - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(coder); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); - if(coder->bitcoder) - { - while(coder->bitcoder->state->next) - { - coder->bitcoder->state = coder->bitcoder->state->next; - } + if(coder->compressed != NULL) + { + free(coder->compressed); + } - while(coder->bitcoder->state->prev) - { - coder->bitcoder->state = coder->bitcoder->state->prev; - free(coder->bitcoder->state->next); - } + if(coder->bitcoder != NULL) + { + while(coder->bitcoder->state->next != NULL) + { + coder->bitcoder->state = coder->bitcoder->state->next; + } + + while(coder->bitcoder->state->prev != NULL) + { + coder->bitcoder->state = coder->bitcoder->state->prev; + free(coder->bitcoder->state->next); + } - free(coder->bitcoder->state); free(coder->bitcoder->context); - } - - free(coder->bitcoder); + free(coder->bitcoder->state); + free(coder->bitcoder); + } } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void initialize_bit_encoder(void) ! +! FUNCTION NAME: void initialize_mq_encoder(void) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -860,87 +844,92 @@ free_bit_encoder(bwc_coder *const coder) ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 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) +initialize_mq_decoder(bwc_coder *const coder, + uint8 const numContexts, + int64 const Lmax) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint8 i; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint8 i; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_bit_coder *bitcoder; - bwc_coder_state *state; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(coder); - assert(coder->compressed); + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_bit_coder *bitcoder; + bwc_coder_state *state; - coder->bitcoder = calloc(1, sizeof(bwc_bit_coder)); - if(!coder->bitcoder) - { + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + assert(coder->compressed); + + coder->bitcoder = calloc(1, sizeof(bwc_bit_coder)); + if(coder->bitcoder == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return 1; - } + return EXIT_FAILURE; + } - bitcoder = coder->bitcoder; + bitcoder = coder->bitcoder; - bitcoder->Lmax = Lmax; - bitcoder->nContext = number_of_contexts; + bitcoder->Lmax = Lmax; + bitcoder->nContext = numContexts; - bitcoder->b = coder->compressed; + bitcoder->b = coder->compressed; - bitcoder->context = calloc(bitcoder->nContext, sizeof(bwc_context_state*)); - if(!bitcoder->context) - { + bitcoder->context = calloc(bitcoder->nContext, sizeof(bwc_context_state*)); + if(bitcoder->context == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return 1; - } + free(coder->bitcoder); + return EXIT_FAILURE; + } - for(i = 0; i < number_of_contexts; ++i) - { + for(i = 0; i < numContexts; ++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->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) - { + bitcoder->state = calloc(1, sizeof(bwc_coder_state)); + if(bitcoder->state == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return 1; - } + free(bitcoder->context); + free(coder->bitcoder); + return EXIT_FAILURE; + } - state = bitcoder->state; - state->b = coder->compressed; + state = bitcoder->state; + state->b = coder->compressed; - fill_lsb(state, bitcoder); + fill_lsb(state, bitcoder); - state->C <<= 0x08; + state->C <<= 0x08; - fill_lsb(state, bitcoder); + fill_lsb(state, bitcoder); - state->C <<= 0x07; - state->t -= 0x07; - state->A = 0x8000; - - return 0; + state->C <<= 0x07; + state->t -= 0x07; + state->A = 0x8000; + + return EXIT_SUCCESS; } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void initialize_bit_encoder(void) ! +! FUNCTION NAME: void initialize_mq_encoder(void) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -964,93 +953,94 @@ initialize_bit_decoder(bwc_coder *const coder, const uint8 number_of_contexts, c ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! ! ! \*----------------------------------------------------------------------------------------------------------*/ uint8 -bit_decode(bwc_bit_coder *const bitcoder, const uint8 k) +mq_bit_decode(bwc_bit_coder *const bitcoder, + uint8 const k) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint16 p; - uint8 x; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(bitcoder); - - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_context_state const **context; - bwc_coder_state *state; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint16 p; + uint8 x; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_context_state const* *context; + bwc_coder_state *state; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(bitcoder); - context = bitcoder->context; - state = bitcoder->state; + context = bitcoder->context; + state = bitcoder->state; - p = context[k]->p; - x = context[k]->sk; + p = context[k]->p; + x = context[k]->sk; - state->A -= p; + state->A -= p; - if((state->C >> 8) >= 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) + { + if(state->A < p) { - fill_lsb(state, bitcoder); + x = 1 - x; + context[k] = context[k]->LPS; } - state->A <<= 1; - state->C <<= 1; - state->t -= 1; - } while (~state->A & 0x8000); - } - } - else - { + 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; - } + { + context[k] = context[k]->MPS; + } else - { - x = 1 - x; - context[k] = context[k]->LPS; - } + { + 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); - } + { + if(state->t == 0) + { + fill_lsb(state, bitcoder); + } + state->A <<= 1; + state->C <<= 1; + state->t -= 1; + } while (~state->A & 0x8000); + } - return x; + return x; } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void initialize_bit_encoder(void) ! +! FUNCTION NAME: void initialize_mq_encoder(void) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -1074,22 +1064,22 @@ bit_decode(bwc_bit_coder *const bitcoder, const uint8 k) ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! ! ! \*----------------------------------------------------------------------------------------------------------*/ uint64 -bit_coder_get_no_bytes(bwc_bit_coder *const bitcoder) +mq_get_no_bytes(bwc_bit_coder *const bitcoder) { - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(bitcoder); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(bitcoder); - return (uint64)(bitcoder->state->b - bitcoder->b) + bitcoder->state->L; + return (uint64)(bitcoder->state->b - bitcoder->b) + bitcoder->state->L; } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void initialize_bit_encoder(void) ! +! FUNCTION NAME: void initialize_mq_encoder(void) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -1113,35 +1103,36 @@ bit_coder_get_no_bytes(bwc_bit_coder *const bitcoder) ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 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) +mq_reset_ptr(bwc_bit_coder *const bitcoder, + uchar *const memory) { - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_coder_state *state; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_state *state; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(bitcoder); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(bitcoder); - state = bitcoder->state; + state = bitcoder->state; - bitcoder->b = memory; + bitcoder->b = memory; - while(state) - { + while(state != NULL) + { state->b = memory; state = state->prev; - } + } } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void initialize_bit_encoder(void) ! +! FUNCTION NAME: void initialize_mq_encoder(void) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -1165,32 +1156,33 @@ bit_coder_reset_ptr(bwc_bit_coder *const bitcoder, uchar *const memory) ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 19.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 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) +mq_get_pass_lengths(bwc_bit_coder *const bitcoder, + bwc_encoded_blk *const encoded_cblk) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint8 j; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint8 j; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_coder_state *state; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_state *state; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(bitcoder); - assert(encoded_cblk); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(bitcoder); + assert(encoded_cblk); - state = bitcoder->state; + state = bitcoder->state; - for(j = encoded_cblk->Z; (j --> 0) && state; state = state->prev) - { + 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 index 48da94c..1b90980 100755 --- a/src/library/tagtree.c +++ b/src/library/tagtree.c @@ -1,82 +1,59 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ - -/************************************************************************************************************\ -|| _ _ _ ____ _ _ _ ___ ____ || -|| | |\ | | | | | | \ |___ || -|| | | \| |___ |___ |__| |__/ |___ || -|| || -\************************************************************************************************************/ +/*====================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This file defines a tagtree procedure used to encode/decode two types of information found || +|| defining in a codeblock in specific quality layer: || +|| || +|| - The inclusion tag records if a codeblock has any contribution || +|| to a quality layer. || +|| - The number of leading bitplanes that are not significant/only || +|| populated by zero bits. || +|| || +|| For more information on the encoding/decoding process please refere to JPEG2000 by || +|| D. S. Taubman and M. W. Marcellin (p. 384). || +|| || +|| ---------------------------------------------------------------------------------------------------------------- || +|| || +|| 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. || +|| || +\*====================================================================================================================*/ +/**********************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\**********************************************************************************************************************/ #include #include #include @@ -86,422 +63,470 @@ #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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/**********************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to properly deallocate a tagtree instance. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! tagtree bwc_tagtree* - Structure defining a tagtree ! +! instance. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 14.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 12.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ void -kill_tagtree(bwc_tagtree* tagtree) +kill_tagtree(bwc_tagtree *const tagtree) { - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(tagtree); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(tagtree); - free(tagtree->nodes); - free(tagtree); - return; + /*--------------------------------------------------------*\ + ! Deallocate the tagtree and its nodes and return to the ! + ! function caller. ! + \*--------------------------------------------------------*/ + free(tagtree->nodes); + tagtree->nodes = NULL; + + 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) +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to setup a tagtree for the number of spatial and tempo- ! +! ral leaves supplied by the function caller. The tagtree will be set up as a bi- ! +! nary tree for a 1-D, a quadtree for a 2-D, a octree for a 3-D and a hextree ! +! for a 4-D problem. If the tagtree already contains a valid tree structure, the ! +! function will reallocate the tagtree to fit the supplied number of leaves and ! +! reinitialize the tree. The leaves and branches will be initialized with the ap- ! +! propriate node and threshold value as well as a pointer to the parent node. ! +! In case the allocation process fails, the function will return to the caller ! +! with an error flag. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! bwc_tagtree* - Structure defining a tagtree ! +! instance. ! +! ! +! leafX, -Y, -Z, -TS unsigned int(64 bit) - Number of spatial and temporal ! +! tagtree leafs. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 14.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 12.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +uchar +initialize_tagtree(bwc_tagtree *tagtree, + uint64 const leafsX, + uint64 const leafsY, + uint64 const leafsZ, + uint64 const leafsTS) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 i = 0; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i; + uint64 levels, numNodes; + uint32 nlX[32] = {0}, nlY[32] = {0}; + uint32 nlZ[32] = {0}, nlTS[32] = {0}; + uint32 j, k, l, n; + uint16 a,b,c,d; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(tagtree); + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_tagtree_node *node; + bwc_tagtree_node *parent_x, *parent_y; + bwc_tagtree_node *parent_z, *parent_ts; + bwc_tagtree_node *tmp; - do - { - tagtree->nodes[i].value = 0xFFFF; - tagtree->nodes[i].threshold = 0; - }while(tagtree->nodes[i++].parent); -} + /*--------------------------------------------------------*\ + ! Calculate the number of nodes and levels for the tagtree ! + ! instance and evaluate the number of spatial and temporal ! + ! leaves and branches for each tagtree level. ! + \*--------------------------------------------------------*/ + for(numNodes = 1, + levels = 0, + nlX[0] = leafsX, + nlY[0] = leafsY, + nlZ[0] = leafsZ, + nlTS[0] = leafsTS; nlX[levels] * nlY[levels] * nlZ[levels] * nlTS[levels] > 1; ++levels) + { + numNodes += nlX[levels] * nlY[levels] * nlZ[levels] * nlTS[levels]; -/*----------------------------------------------------------------------------------------------------------*\ -! 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); + 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; + } - 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) - { + /*--------------------------------------------------------*\ + ! Reallocate the nodes, loop over them and assign the in- ! + ! dices of the leaves and branches. Save the number of ! + ! spatial and temporal leaves in the tagtree structure. ! + \*--------------------------------------------------------*/ + tmp = realloc(tagtree->nodes, numNodes * sizeof(bwc_tagtree_node)); + if(tmp == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return 0; - } + return EXIT_FAILURE; + } + else + { + tagtree->nodes = tmp; + node = tmp; + } - 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) - { + for(i = 0; i < numNodes; ++i) + { node->index = i; ++node; - } + } - tagtree->leavesX = leafsX; - tagtree->leavesY = leafsY; - tagtree->leavesZ = leafsZ; - tagtree->leavesTS = leafsTS; + 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) - { + /*--------------------------------------------------------*\ + ! Walk through the tagtree and set up all leaf and branch ! + ! nodes. Every parental node is initialized to have a max- ! + ! imum of 2 children in each spatial and temporal dir. ! + \*--------------------------------------------------------*/ + 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) + { + if(d >> 1) { - parent_z += nlX[n+1] * nlY[n+1]; - c = 0; + parent_ts += nlX[n+1] * nlY[n+1] * nlZ[n+1]; + d = 0; } - for(j = 0, b = 0, parent_y = parent_z; j < nlY[n]; ++j, ++b) + for(k = 0, c = 0, parent_z = parent_ts; k < nlZ[n]; ++k, ++c) { - 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++; - } + 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; + } + /*--------------------------------------------------------*\ + ! Initialize the current node with a pointer to its parent ! + ! node index and initial value and treshold values. ! + \*--------------------------------------------------------*/ + node->parent = parent_x; + node->value = 0xFFFF; + node->threshold = 0; + node++; + } + } } - } - } - } - reset_tagtree(tagtree); - return tagtree; + } + } + return EXIT_SUCCESS; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to store a value in a tagtree leaf identified by its leaf ! +! index. Additionally, the function will loop through and store the value in all ! +! associated tagtree branches that have a smaller node value. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! tagtree bwc_tagtree* - Structure defining a tagtree ! +! instance. ! +! ! +! index unsigned int(64 bit) - Tagtree leaf index for which ! +! the value is to be retrieved. ! +! ! +! value unsigned int(16 bit) - Value stored in a tagree leave ! +! which is identified by its ! +! leave index. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 14.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 12.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +void +tagtree_set_value(bwc_tagtree *const tagtree, + uint64 const index, + uint16 const value) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_tagtree_node *node; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(tagtree); + assert(index < tagtree->leavesX * tagtree->leavesY * + tagtree->leavesZ * tagtree->leavesTS); + assert(tagtree->nodes[index].value == 0xFFFF); + assert(value < 0xFFFF); + + /*--------------------------------------------------------*\ + ! Walk through the tree, from leaf to root, and store the ! + ! specified value in every node with a smaller node value. ! + \*--------------------------------------------------------*/ + node = &tagtree->nodes[index]; + do + { + node->value = value; + node = node->parent; + } while(node && (node->value > value)); +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to extract a leaf value from a tagtree according to the ! +! leaf index supplied by the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! tagtree bwc_tagtree* - Structure defining a tagtree ! +! instance. ! +! ! +! index unsigned int(64 bit) - Tagtree leaf index for which ! +! the value is to be retrieved. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned int(16 bit) - Value stored in a tagree leave ! +! which is identified by its ! +! leave index. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 14.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 12.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +uint16 +tagtree_get_value(bwc_tagtree const *const tagtree, + uint64 const index) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(tagtree); + assert(index < tagtree->leavesX * tagtree->leavesY * + tagtree->leavesZ * tagtree->leavesTS); + assert(tagtree->nodes[index].value != 0xFFFF); + + /*--------------------------------------------------------*\ + ! Return the leaf value to the function caller. ! + \*--------------------------------------------------------*/ + return tagtree->nodes[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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to extract a leaf value from a tagtree according to the ! +! leaf index supplied by the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! tagtree bwc_tagtree* - Structure defining a tagtree ! +! instance. ! +! ! +! index unsigned int(64 bit) - Tagtree leaf index for which ! +! the value is to be retrieved. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned int(16 bit) - Value stored in a tagree leave ! +! which is identified by its ! +! leave index. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 14.06.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 12.05.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ void -encode_tagtree(bwc_tagtree *const tagtree, bwc_stream *const stream, const uint32 threshold, const uint32 leaf_index, const uchar estimate) +encode_tagtree(bwc_tagtree *const tagtree, + bwc_stream *const stream, + uint32 const threshold, + uint32 const index, + uchar const estimate) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint32 threshold_tmp, threshold_min; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint32 threshold_tmp, threshold_min; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_tagtree_node *node; - bwc_tagtree_node **branch_ptr, *branch[32]; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_tagtree_node *node; + bwc_tagtree_node **branch_ptr, *branch[64]; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(tagtree); - assert(stream); - assert(leaf_index < (tagtree->leavesX * tagtree->leavesY * tagtree->leavesZ * tagtree->leavesTS)); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(tagtree); + assert(stream); + assert(index < (tagtree->leavesX * tagtree->leavesY * + tagtree->leavesZ * tagtree->leavesTS)); - node = &tagtree->nodes[leaf_index]; - branch_ptr = branch; - - while(node->parent) - { + /*--------------------------------------------------------*\ + ! Set up a pointer array that stores all tagtree nodes, ! + ! from leaf to root, for the specified leaf index. ! + \*--------------------------------------------------------*/ + node = &tagtree->nodes[index]; + branch_ptr = branch; + + while(node->parent) + { *branch_ptr++ = node; - node = node->parent; - } + node = node->parent; + } - for(threshold_min = 0; ; node = *--branch_ptr) - { + /*--------------------------------------------------------*\ + ! Walk through the pointer array from root to leaf node. ! + \*--------------------------------------------------------*/ + for(threshold_min = 0; ; node = *--branch_ptr) + { + /*--------------------------------------------------------*\ + ! Evaluate the temporary threshold used to encode the node ! + ! value. ! + \*--------------------------------------------------------*/ 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_tmp = threshold_min; + } + + /*--------------------------------------------------------*\ + ! Iteratively increase the threshold and emit a 0 to the ! + ! stream until the loop conditions are meet. Once the node ! + ! value becomes smaller than the threshold emit a 1. ! + \*--------------------------------------------------------*/ + while((node->value >= threshold_tmp) && + (threshold > threshold_tmp)) + { + threshold_tmp++; + if(node->value >= threshold_tmp) + { + emit_bit(stream, 0); + } + else + { + emit_bit(stream, 1); + } + } + /*--------------------------------------------------------*\ + ! Increase the minimum threshold value and update the node ! + ! threshold for a live encoding procedure. ! + \*--------------------------------------------------------*/ threshold_min = MIN(node->value, threshold_tmp); - if(!estimate) - { - node->threshold = threshold_tmp; - } + if(estimate == 0) + { + node->threshold = threshold_tmp; + } - if(node == &tagtree->nodes[leaf_index]) - { - break; - } - } + if(node == &tagtree->nodes[index]) + { + break; + } + } } /*----------------------------------------------------------------------------------------------------------*\ @@ -529,46 +554,55 @@ encode_tagtree(bwc_tagtree *const tagtree, bwc_stream *const stream, const uint3 ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 14.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! +! 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) +decode_tagtree(bwc_tagtree *const tagtree, + bwc_stream *const stream, + uint32 const threshold, + uint32 const index) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint32 threshold_min; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint32 threshold_min; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_tagtree_node *node; - bwc_tagtree_node **branch_ptr, *branch[32]; + /*-----------------------*\ + ! 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)); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(tagtree); + assert(stream); + assert(index < (tagtree->leavesX * tagtree->leavesY * + tagtree->leavesZ * tagtree->leavesTS)); - node = &tagtree->nodes[leaf_index]; - branch_ptr = branch; - - while(node) - { + node = &tagtree->nodes[index]; + branch_ptr = branch; + + while(node != NULL) + { if(node->value == 0xFFFF) - { - node->value = 0; - } + { + node->value = 0; + } *branch_ptr++ = node; node = node->parent; - } + } - for(*branch_ptr--, node = *branch_ptr--, threshold_min = 0; ; node = *branch_ptr--) + (void)*branch_ptr--; + threshold_min = 0; + + do { + node = *branch_ptr--; + if(node->threshold < threshold_min) { node->value = threshold_min; @@ -577,18 +611,14 @@ decode_tagtree(bwc_tagtree *const tagtree, bwc_stream *const stream, const uint3 while((node->value == node->threshold) && (node->threshold < threshold)) { node->threshold++; - if(!bwc_get_bit(stream)) + if(!get_bit(stream)) { node->value++; } } threshold_min = MIN(node->value, node->threshold); + } while (node != &tagtree->nodes[index]); - if(node == &tagtree->nodes[leaf_index]) - { - break; - } - } - return (node->value < threshold) ? 0 : 1; + return (node->value < threshold) ? 0 : 1; } \ No newline at end of file diff --git a/src/library/tier1.c b/src/library/tier1.c index 3c47bdb..8b12982 100755 --- a/src/library/tier1.c +++ b/src/library/tier1.c @@ -1,75 +1,53 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ - -/************************************************************************************************************\ -|| _ _ _ ____ _ _ _ ___ ____ || -|| | |\ | | | | | | \ |___ || -|| | | \| |___ |___ |__| |__/ |___ || -|| || -\************************************************************************************************************/ +/*====================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This file describes a set of functions that can be used to de-/encode bwc codeblocks || +|| described by the bwc_field structure according to the embedded block coding paradigm || +|| described by the JPEG 2000 standard. For more information please refere to JPEG2000 || +|| by D. S. Taubman and M. W. Marcellin. || +|| || +|| ---------------------------------------------------------------------------------------------------------------- || +|| || +|| 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. || +|| || +\*====================================================================================================================*/ +/**********************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\**********************************************************************************************************************/ #include #include #include @@ -78,144 +56,146 @@ #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: ! +! ------------ ! +! This macro defines a simple operator used to insert a 4 bit marker after every ! +! cleanup pass in the bwc codestream to allow for error resilient decoding. For ! +! further information see JPEG2000 by D. S. Taubman and M. W. Marcellin (p.509). ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 01.02.2019 Patrick Vogler B87D120 V 0.1.0 Macros created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +#define encode_segmark(bitcoder) \ +{ \ + mq_bit_encode(bitcoder, 1, CONTEXT_UNI); \ + mq_bit_encode(bitcoder, 0, CONTEXT_UNI); \ + mq_bit_encode(bitcoder, 1, CONTEXT_UNI); \ + mq_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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/**********************************************************************************************************************\ +|| ____ _ ____ ___ ____ _ ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || +|| | __ | | | |__] |__| | | | | |\ | [__ | |__| |\ | | [__ || +|| |__] |___ |__| |__] | | |___ |___ |__| | \| ___] | | | | \| | ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! DESCRIPTION: ! +! ------------ ! +! These constants define lookup tables used for distortion estimation during the ! +! significance propagation (TS) and magnitude refinement (TM) pass. The individ- ! +! ual 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 ener- ! +! gy gain factor for subband b_i, 𝛥_i the quantization step-size, ν_i the quanti- ! +! zation magnitude, νtilde the fraction part of ν_i, ν_i^p the quantization mag- ! +! nitude 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 specific bitplane. ! +! ! +! CONSTANTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! DISTORTION_TM_LUT - Distortion estimation lookup ! +! table for the magnitude refine- ! +! ment pass. ! +! ! +! DISTORTION_TS_LUT - Distortion estimation lookup ! +! table for the significance ! +! propagation pass. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 23.01.2019 Patrick Vogler B87D120 V 0.1.0 Constants created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ 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}; +{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}; +{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] = +/*--------------------------------------------------------------------------------------------------------------------*\ +! DESCRIPTION: ! +! ------------ ! +! These constants define simple lookup tables used to speed up the en/decoding ! +! process. ! +! ! +! CONSTANTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! FRAC2LOG - Lookup table used to convert ! +! the fractional bits of a 64- ! +! bit real to the log2 format. ! +! ! +! LEADING_ZERO - Lookup table used to evaluate ! +! the number of leading zeros ! +! in a pseudo 4-bit integer. ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 15.02.2019 Patrick Vogler B87D120 V 0.1.0 Constants created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +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, @@ -233,19 +213,44 @@ static const uint16 frac2log[256] = 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 int32 LEADING_ZERO[15] = +{0, 3, 0, 2, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0}; + +/*--------------------------------------------------------------------------------------------------------------------*\ +! DESCRIPTION: ! +! ------------ ! +! These constants define simple lookup tables for context assignment during sig- ! +! nificance coding. For more information please refer to JPEG2000 by David S. ! +! Taubman and Michael W. Marcellin (p. 355). ! +! ! +! CONSTANTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! SIG2CONTEXT_L - Context assignment for signif- ! +! icance coding of low-pass (L) ! +! or vertical high-pass (LH) ! +! subband. ! +! ! +! SIG2CONTEXT_H - Context assignment for signif- ! +! icance coding of horizontal ! +! high-pass (HL) subband. ! +! ! +! SIG2CONTEXT_HH - Context assignment for signif- ! +! icance coding of diagonal high- ! +! -pass(HH) subband. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 08.03.2019 Patrick Vogler B87D120 V 0.1.0 Constants created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ 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, @@ -279,78 +284,110 @@ static const uint8 SIG2CONTEXT_HH[45] = 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] = +/*--------------------------------------------------------------------------------------------------------------------*\ +! DESCRIPTION: ! +! ------------ ! +! These constants define simple lookup tables for context assignment during sign ! +! coding. For more information please refer to JPEG2000 by David S. Taubman and ! +! Michael W. Marcellin (p. 358 & 359). ! +! ! +! CONSTANTS: ! +! ---------- ! +! Name Description ! +! ---- ----------- ! +! SIG2XI - Net sign bias assignment of the ! +! horizontal and vertical neigh- ! +! bours. ! +! ! +! XI2CONT - Context (first column) and ! +! flipping factor (second col- ! +! umn) assignment. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 08.03.2019 Patrick Vogler B87D120 V 0.1.0 Constants created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static const uint8 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] = +static const uint8 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/**********************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function resets the array used to store the sign, magnitude, bitplanes ! +! and significance state of the codeblock stripes. This function should be ! +! called after encoding a codeblock. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! cblk bwc_coder_stripe* - Defines the sign, magnitude ! +! bitplane and state of a stripe. ! +! ! +! width, height, ... unsigned int(64 bit) - Spatial and temporal dimension ! +! of a codeblock. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 10.12.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -cblkreset_fwd(bwc_coder_stripe *const cblk, uint64 cblksize) +cblkreset_fwd(bwc_coder_stripe *const cblk, + uint64 const width, + uint64 const height, + uint64 const depth, + uint64 const dt) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 i; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_coder_stripe buff; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe buff; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(cblk); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(cblk); - /*--------------------------------------------------------*\ - ! Walk through the cblk memory block. ! - \*--------------------------------------------------------*/ - for(i = 0; i < cblksize; ++i) - { + for(i = 0; i < (width * ceil((double)height/4) * depth * dt); ++i) + { /*--------------------------------------------------------*\ ! Save the sample bit and context memory address in a tem- ! ! porary variables. ! @@ -359,2087 +396,2895 @@ cblkreset_fwd(bwc_coder_stripe *const cblk, uint64 cblksize) 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.! + ! Reset the stripe structure and 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)); + memset(buff.bit, 0, sizeof(uint8) * PREC_BIT); + memset(buff.sample, 0, sizeof(uint64) * 4); /*--------------------------------------------------------*\ - ! Store the memory address of the sample, bit and context ! - ! variables in the bwc_coder_stripe structure. ! + ! Restore the memory address of the sample, bit and con- ! + ! text 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function resets the array used to store the sign, magnitude, bitplanes ! +! and significance state of the codeblock stripes. This function should be ! +! called before decoding a codeblock. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! cblk bwc_coder_stripe* - Defines the sign, magnitude ! +! bitplane and state of a stripe. ! +! ! +! width, height, ... unsigned int(64 bit) - Spatial and temporal dimension ! +! of a codeblock. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 10.12.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -cblkreset_inv(bwc_coder_stripe *const cblk, const uint64 width, const uint64 height, - const uint64 depth, const uint64 dt) +cblkreset_inv(bwc_coder_stripe *const cblk, + uint64 const width, + uint64 const height, + uint64 const depth, + uint64 const 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 INT VARIABLES: ! + \*-----------------------*/ + uint64 i; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_coder_stripe buff; + uint64 limit; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(cblk); + uint64 cblk_stripe; - /*--------------------------------------------------------*\ - ! 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); + uint64 x, y, z, t; - /*--------------------------------------------------------*\ - ! 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) - { + int64 idx_u, idx_r; + int64 idx_d, idx_l; + + uint8 s; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe buff; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(cblk); + + /*--------------------------------------------------------*\ + ! Evaluate the number of stripes that are to be copied. ! + \*--------------------------------------------------------*/ + 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 stripe structure. ! + \*--------------------------------------------------------*/ + 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(y = 0; y < cblk_stripe; i += width, ++y) { - 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; + 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)); + /*--------------------------------------------------------*\ + ! Reset the stripe structure and 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; + /*--------------------------------------------------------*\ + ! Restore the memory address of the sample, bit and con- ! + ! text 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); + /*--------------------------------------------------------*\ + ! Evaluate the appropriate index for the stripe neighbours ! + ! and set the state pointers. Neighbours that fall outside ! + ! of the codeblock boundaries are set to dummy variables. ! + \*--------------------------------------------------------*/ + 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]; - } + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function walks through the wavelet coefficients in the current codeblock ! +! in a stripe pattern and saves its sample magnitudes as well as the sign and ! +! magnitude bitplanes in the bwc_coder_stripe structure. Here, the 8-bit sign ! +! and magnitude fields are used to store two adjacent stripes to reduce the mem- ! +! ory footprint. ! +! Furthermore, the pointer to the neighboring state variables are initialized. ! +! States that fall outside of the codeblock boundaries are set to dummy variables ! +! to uncouple the current block from its neighbors. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! destination bwc_coder_stripe* - Defines the sign, magnitude ! +! bitplane and state of a stripe. ! +! ! +! source bwc_float* - Wavelet coefficients making up ! +! up a codeblock. ! +! ! +! cblkaccess bwc_cblk_access* - Access to a parameter code- ! +! block and subband structure. ! +! ! +! width, height, depth unsigned int(64 bit) - Spatial dimension of a code- ! +! block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ 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) +cblkcopy_forward(bwc_coder_stripe *const destination, + bwc_float *const source, + bwc_cblk_access *const access, + uint64 const width, + uint64 const height, + uint64 const 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 INT VARIABLES: ! + \*-----------------------*/ + bwc_raw buff, sign_mask; + uint64 bit_mask, limit; - /*-----------------------*\ - ! DEFINE FLOAT VARIABLES: ! - \*-----------------------*/ - bwc_float qt_step_size; + uint64 cblk_width, cblk_height; + uint64 cblk_depth, cblk_stripe; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_cblk_inf *cblk_info; - bwc_sample *tmp; + uint64 incrX, incrY, incrZ; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(destination); - assert(cblkaccess); - assert(source); + uint64 i, x, y, z, t; - /*--------------------------------------------------------*\ - ! Save the codeblock info structure to a temporary varia- ! - ! ble to make the code more readable. ! - \*--------------------------------------------------------*/ - cblk_info = &cblkaccess->codeblock->info; + uint64 X0, Y0, Z0, TS0; + uint64 X1, Y1, Z1, TS1; - /*--------------------------------------------------------*\ - ! Setup a bitmask to access the sign bit position. ! - \*--------------------------------------------------------*/ - sign_mask = ~((bwc_raw)0x01 << PREC_BIT); + int64 idx_u, idx_r; + int64 idx_d, idx_l; - /*--------------------------------------------------------*\ - ! 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; + uint16 cblk_dt; - /*--------------------------------------------------------*\ - ! 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; + uint8 b, s; + uint8 Kmax; - X1 = cblk_info->X1; - Y1 = cblk_info->Y1; - Z1 = cblk_info->Z1; - TS1 = cblk_info->TS1; + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + bwc_float qt_step_size; - /*--------------------------------------------------------*\ - ! 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; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_cblk_inf *cblk_info; + bwc_sample *tmp; - /*--------------------------------------------------------*\ - ! 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); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(destination); + assert(access); + assert(source); - /*--------------------------------------------------------*\ - ! Calculate the pointer increments used to loop through ! - ! the source memory. ! - \*--------------------------------------------------------*/ - incrX = width; - incrY = width * (height - (Y1 - Y0)); - incrZ = width * height * (depth - (Z1 - Z0)); + /*--------------------------------------------------------*\ + ! Save the codeblock info structure as well as the code- ! + ! block dimensions to temporary variables to make the code ! + ! more readable. ! + \*--------------------------------------------------------*/ + cblk_info = &access->codeblock->info; - /*--------------------------------------------------------*\ - ! Associate the temporary pointer to the starting points ! - ! of the source memory. ! - \*--------------------------------------------------------*/ - tmp = &source[X0 + width * (Y0 + height * (Z0 + depth * TS0))]; + X0 = cblk_info->X0; + Y0 = cblk_info->Y0; + Z0 = cblk_info->Z0; + TS0 = cblk_info->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) - { + X1 = cblk_info->X1; + Y1 = cblk_info->Y1; + Z1 = cblk_info->Z1; + TS1 = cblk_info->TS1; + + /*--------------------------------------------------------*\ + ! Initialize the quantization step size as well as the ! + ! sign bit position bit mask and the index of the most ! + ! significant bitplane. ! + \*--------------------------------------------------------*/ + qt_step_size = access->subband->control.qt_eff_step_size; + sign_mask = ~((bwc_raw)0x01 << PREC_BIT); + Kmax = 0; + + /*--------------------------------------------------------*\ + ! Calculate the width, height, depth and dt as well as the ! + ! maximum number of stripes for the current codeblock. ! + \*--------------------------------------------------------*/ + cblk_width = X1 - X0; + cblk_height = Y1 - Y0; + cblk_depth = Z1 - Z0; + cblk_dt = TS1 - TS0; + + cblk_stripe = ceil((double)cblk_height/4); + + /*--------------------------------------------------------*\ + ! Associate the temporary pointer with the codeblock start-! + ! ing point in the source memory and calculate the incre- ! + ! ments to loop over its wavelet coefficients. ! + \*--------------------------------------------------------*/ + tmp = (bwc_sample*)&source[X0 + width * (Y0 + height * (Z0 + depth * TS0))]; + + incrX = width; + incrY = width * (height - (Y1 - Y0)); + incrZ = width * height * (depth - (Z1 - Z0)); + + /*--------------------------------------------------------*\ + ! Walk through all wavelet coefficients in the current ! + ! codeblock in a stripe pattern and save the sign and ! + ! significant magnitude bits in the stripe structure. ! + \*--------------------------------------------------------*/ + 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(y = 0; y < cblk_stripe; i += cblk_width, ++y) { - 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); + for(s = 0, bit_mask = 0x08, 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); + /*--------------------------------------------------------*\ + ! Evaluate the absolute value of the wavelet coefficient ! + ! and save it in the sample array for distortion calcula- ! + ! tion. ! + \*--------------------------------------------------------*/ + 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; + 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 bitplane and stripe and update ! + ! the index of the most significant bitplane. ! + \*--------------------------------------------------------*/ + for(b = 0; buff >>= 1; ++b) + destination[x + i].bit[b] |= bit_mask * (buff & 0x01); - /*--------------------------------------------------------*\ - ! 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++; - } + Kmax = MAX(Kmax, b); - /*--------------------------------------------------------*\ - ! Update the index of the most significant bitfield. ! - \*--------------------------------------------------------*/ - Kmax = MAX(Kmax, b); + /*--------------------------------------------------------*\ + ! Evaluate the appropriate index for the stripe neighbours ! + ! and set the state pointers. Neighbours that fall outside ! + ! of the codeblock boundaries are set to dummy variables. ! + \*--------------------------------------------------------*/ + 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); - /*--------------------------------------------------------*\ - ! 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; + 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]; + } + bit_mask >>= 1; + tmp += incrX; + } } - } - /*--------------------------------------------------------*\ - ! Increment to the next column. ! - \*--------------------------------------------------------*/ - tmp += incrY; - } - /*--------------------------------------------------------*\ - ! Increment to the next spatial slice. ! - \*--------------------------------------------------------*/ + tmp += incrY; + } tmp += incrZ; - } - /*--------------------------------------------------------*\ - ! Save the most significant bitfield of the current sub- ! - ! band in the appropriate subband structure. ! - \*--------------------------------------------------------*/ - cblkaccess->codeblock->control.K = Kmax; + } + /*--------------------------------------------------------*\ + ! Save the most significant bitplane of the current sub- ! + ! band in the appropriate subband structure. ! + \*--------------------------------------------------------*/ + access->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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function walks through the decompressed codeblock stripes and assembles ! +! and copies the decompressed wavelet coefficients to the parameter data memory ! +! block. If the assembled wavelet coefficient is larger than zero a correction ! +! is applied in case any coding passes had been dropped during rate control. ! +! For more information refer to JPEG2000 by David S. Taubman and Michael W. ! +! Marcellin. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! source bwc_coder_stripe* - Defines the sign, magnitude ! +! bitplane and state of a stripe. ! +! ! +! destination bwc_float* - Wavelet coefficients making up ! +! up a codeblock. ! +! ! +! access bwc_cblk_access* - Access to a parameter code- ! +! block and subband structure. ! +! ! +! width, height, depth unsigned int(64 bit) - Spatial dimension of a code- ! +! block. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ 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) +cblkcopy_inverse(bwc_coder_stripe *const source, + bwc_float *const destination, + bwc_cblk_access *const access, + uint64 const width, + uint64 const height, + uint64 const 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 INT VARIABLES: ! + \*-----------------------*/ + uint64 cblk_width, cblk_height; + uint64 cblk_depth, cblk_stripe; - /*-----------------------*\ - ! DEFINE FLOAT VARIABLES: ! - \*-----------------------*/ - bwc_float qt_step_size; + uint64 bit_shift, buff, limit; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_cblk_inf *cblk_info; - bwc_sample *tmp; + uint64 incrX, incrY, incrZ; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(destination); - assert(cblkaccess); - assert(source); + uint64 i, x, y, z, t; - /*--------------------------------------------------------*\ - ! Save the codeblock info structure to a temporary varia- ! - ! ble to make the code more readable. ! - \*--------------------------------------------------------*/ - cblk_info = &cblkaccess->codeblock->info; + uint64 X0, Y0, Z0, TS0; + uint64 X1, Y1, Z1, TS1; - /*--------------------------------------------------------*\ - ! Initialize the quantization step size and the index of ! - ! the most significant bitfield. ! - \*--------------------------------------------------------*/ - qt_step_size = cblkaccess->subband->control.qt_effective_step_size; + uint16 cblk_dt; - /*--------------------------------------------------------*\ - ! Safe the last bitplane and codingpass to temporary vari- ! - ! able to make the code more readable. ! - \*--------------------------------------------------------*/ - bitplane = source->bitplane; - codingpass = source->codingpass; + uint8 bitplane; + uint8 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; + uint8 s; + int8 b; - X1 = cblk_info->X1; - Y1 = cblk_info->Y1; - Z1 = cblk_info->Z1; - TS1 = cblk_info->TS1; + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + bwc_float qt_step_size; - /*--------------------------------------------------------*\ - ! 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; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_cblk_inf *cblk_info; + bwc_sample *tmp; - /*--------------------------------------------------------*\ - ! 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); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(destination); + assert(access); + assert(source); - /*--------------------------------------------------------*\ - ! Calculate the pointer increments used to loop through ! - ! the destination memory. ! - \*--------------------------------------------------------*/ - incrX = width; - incrY = width * (height - (Y1 - Y0)); - incrZ = width * height * (depth - (Z1 - Z0)); + /*--------------------------------------------------------*\ + ! Save the codeblock info structure as well as the code- ! + ! block dimensions to temporary variables to make the code ! + ! more readable. ! + \*--------------------------------------------------------*/ + cblk_info = &access->codeblock->info; - /*--------------------------------------------------------*\ - ! Associate the temporary pointer to the starting points ! - ! of the destination memory. ! - \*--------------------------------------------------------*/ - tmp = &destination[X0 + width * (Y0 + height * (Z0 + depth * TS0))]; + X0 = cblk_info->X0; + Y0 = cblk_info->Y0; + Z0 = cblk_info->Z0; + TS0 = cblk_info->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) - { + X1 = cblk_info->X1; + Y1 = cblk_info->Y1; + Z1 = cblk_info->Z1; + TS1 = cblk_info->TS1; + + /*--------------------------------------------------------*\ + ! Initialize the quantization step size as well as the ! + ! final decoded bitplane and coding pass. ! + \*--------------------------------------------------------*/ + qt_step_size = access->subband->control.qt_eff_step_size; + + codingpass = source->codingpass; + bitplane = source->bitplane; + + /*--------------------------------------------------------*\ + ! Calculate the width, height, depth and dt as well as the ! + ! maximum number of stripes for the current codeblock. ! + \*--------------------------------------------------------*/ + cblk_width = X1 - X0; + cblk_height = Y1 - Y0; + cblk_depth = Z1 - Z0; + cblk_dt = TS1 - TS0; + + cblk_stripe = ceil((double)cblk_height/4); + + /*--------------------------------------------------------*\ + ! Associate the temporary pointer with the codeblock start-! + ! ing point in the source memory and calculate the incre- ! + ! ments to loop over its wavelet coefficients. ! + \*--------------------------------------------------------*/ + tmp = (bwc_sample*)&destination[X0 + width * (Y0 + height * (Z0 + depth * TS0))]; + + incrX = width; + incrY = width * (height - (Y1 - Y0)); + incrZ = width * height * (depth - (Z1 - Z0)); + + /*--------------------------------------------------------*\ + ! Walk through all wavelet coefficients in the current ! + ! codeblock in a stripe pattern and save the wavelet coef- ! + ! ficients in the codeblock memory block. ! + \*--------------------------------------------------------*/ + 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(y = 0; y < cblk_stripe; i += cblk_width, ++y) { - 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; - } + for(s = 0, bit_shift = 0x03, limit = cblk_height - y * 4; s < 4 && s < limit; ++s) + { + for(x = 0; x < cblk_width; ++x) + { + /*--------------------------------------------------------*\ + ! Assemble the absolute value of the wavelet coefficient ! + ! from the decoded bitplanes. ! + \*--------------------------------------------------------*/ + 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); - } - } + /*--------------------------------------------------------*\ + ! If the assembled value is larger than zero, apply a cor- ! + ! rection for the dropped coding passes, dequantize the ! + ! coefficient and apply the sign bit to it. ! + \*--------------------------------------------------------*/ + if(buff > 0) + { + tmp[x].f = (bwc_float)buff; + buff = source[x + i].pi >> bit_shift; + tmp[x].f += (1UL << (bitplane + ((codingpass == 0 || (buff & 0x01)) ? 0 : 1))) * 0.475f; - /*--------------------------------------------------------*\ - ! 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; + tmp[x].f *= qt_step_size; + tmp[x].raw |= SIGN * ((source[x + i].xi >> bit_shift) & 0x01); + } + } + bit_shift--; + tmp += incrX; + } } - } - /*--------------------------------------------------------*\ - ! Increment to the next column. ! - \*--------------------------------------------------------*/ - tmp += incrY; - } - /*--------------------------------------------------------*\ - ! Increment to the next spatial slice. ! - \*--------------------------------------------------------*/ + tmp += incrY; + } 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function describes the significance propagation encoding pass for a bwc ! +! codeblock. This is the first coding pass applied to each bitplane, encoding ! +! those samples that have a significant neighborhood - at least one of its neigh- ! +! bors is significant. Specifically, this coding pass encodes those samples that ! +! are most likely to become significant in the current bitplane b. ! +! The significance propagation pass is omitted for the most significant bitplane ! +! since no samples have a significant neighborhood, yet. ! +! Concurrently, the function will evaluate and return an estimation for the dis- ! +! tortion incurred if the coding pass is dropped from the final codestream. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! coder bwc_coder* - Structure defining and control- ! +! ling the encoding procedure ! +! for a codeblock. ! +! ! +! b signed int(8 bit) - Bitfield encoded in the cur- ! +! rent coding pass. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uint64 - Distortion estimation for the ! +! current coding pass. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static uint64 -significance_propagation_enc_pass(bwc_coder *const coder, const int8 b) +significance_propagation_enc_pass(bwc_coder *const coder, + int8 const 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 INT VARIABLES: ! + \*-----------------------*/ + uint64 i, j; + uint64 k, x; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_coder_stripe *stripe; + int64 mse; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(coder); + uint16 k_h, k_v, k_d; + uint16 k_sig; - 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; + uint16 xi_h, xi_v; - for(i = 0, k = 0; i < coder->no_slice; ++i) - { + uint8 bit_mask, stripe_mask; + + uint8 dist_shift, dist_corr, l; + + uint8 buff; + + uint8 bit, rest; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe *stripe; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + stripe = coder->data; + + /*--------------------------------------------------------*\ + ! Evaluate if the number of vertical samples is divisable ! + ! by 4 and set up an appropriate mask for the last, not ! + ! fully populated, stripe. ! + \*--------------------------------------------------------*/ + rest = 4 - (coder->height & 0x03); + stripe_mask = ~((0x0F >> ((coder->height & 0x03))) | 0xF0); + + /*--------------------------------------------------------*\ + ! Evaluate the up (_shift) or down (_corr) shift parame- ! + ! ters used to position a bit of the current bitplane at ! + ! the appropriate 5th position for the dis. lookup tables. ! + \*--------------------------------------------------------*/ + dist_shift = (b < 5) ? 0 : (b - 5); + dist_corr = (b < 5) ? (5 - b) : 0; + + /*--------------------------------------------------------*\ + ! Walk through all stripes in the codeblock and encode all ! + ! sample bits with a significant neighborhood. ! + \*--------------------------------------------------------*/ + for(i = 0, k = 0, mse = 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(x = 0; x < coder->width; ++x, ++k) { - 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) + /*--------------------------------------------------------*\ + ! Check if a sample in the current stripe has not yet be- ! + ! come significant. If true, loop over the current stripe ! + ! and evaluate the non-significant sample bits. ! + \*--------------------------------------------------------*/ + if((stripe[k].sigma^0xF) != 0) + { + for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> 0; bit_mask >>= 1) + { + if((bit_mask & stripe[k].sigma) == 0) { - 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; + /*--------------------------------------------------------*\ + ! Evaluate the intermediate sig. context labels for the ! + ! horizontal, vertical and diagonal sample neighbours. ! + \*--------------------------------------------------------*/ + k_h = (bit_mask & stripe[k].stripe_l->sigma) + + (bit_mask & stripe[k].stripe_r->sigma); - 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)); - } + k_v = ((bit_mask & (stripe[k].sigma >> 1)) + + (bit_mask & (stripe[k].sigma << 1))); - 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]); + 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))); - mse += DISTORTION_TS_LUT[((stripe[k].sample[l] >> dist_shift) << dist_corr) & 0x1F]; - stripe[k].sigma |= bit_mask; + /*--------------------------------------------------------*\ + ! Adjust the intermediate context labels in case the sam- ! + ! ple borders with an upper or lower stripe neighbor. ! + \*--------------------------------------------------------*/ + 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; + } + + /*--------------------------------------------------------*\ + ! Calculate the context label for the current sample. If ! + ! the neighborhood is significant (k_sig>0), proceed with ! + ! encoding the sample bit. ! + \*--------------------------------------------------------*/ + k_sig = ((15 * k_h + 5 * k_v + k_d) >> l); + + if(k_sig != 0) + { + /*--------------------------------------------------------*\ + ! Encode the bit for the current sample using the suitable ! + ! context extracted from the sig2context lookup table. If ! + ! the bit is significant, proceed with encoding the sign. ! + \*--------------------------------------------------------*/ + mq_bit_encode(coder->bitcoder, (uchar)((bit >> l) & 0x01), coder->sig2context[k_sig]); + + if((bit_mask & bit) != 0) + { + /*--------------------------------------------------------*\ + ! Evaluate the intermediate net sign bias quantities for ! + ! the horizontal and vertical sample neighbours. ! + \*--------------------------------------------------------*/ + 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; + + /*--------------------------------------------------------*\ + ! Adjust the intermediate net sign bias quantities in case ! + ! the sample borders with an upper or lower neighbor. ! + \*--------------------------------------------------------*/ + 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)); + } + + /*--------------------------------------------------------*\ + ! Evaluate the sample sign as well as the net sign bias ! + ! quantities. Encode the sample sign using the suitable ! + ! flip factor XI2CONT[*][1] and context XI2CONT[*][0]. ! + \*--------------------------------------------------------*/ + buff = (bit_mask & stripe[k].xi) >> l; + + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + mq_bit_encode(coder->bitcoder, (uchar)(buff^XI2CONT[(xi_h << 2) | xi_v][1]), + XI2CONT[(xi_h << 2) | xi_v][0]); + + /*--------------------------------------------------------*\ + ! Evaluate and add the error of omitting the current bit ! + ! to the coding pass distortion estimation. Additionally, ! + ! set the significance state for the current sample. ! + \*--------------------------------------------------------*/ + buff = (uint8)((stripe[k].sample[l] >> dist_shift) << dist_corr); + mse += DISTORTION_TS_LUT[buff & 0x1F]; + stripe[k].sigma |= bit_mask; + } + /*--------------------------------------------------------*\ + ! Set the coding pass membershib for the current sample to ! + ! remove it from the other coding passes. ! + \*--------------------------------------------------------*/ + stripe[k].pi |= bit_mask; + } } - - stripe[k].pi |= bit_mask; - } - } - else - { - stripe[k].pi ^= (stripe[k].pi & bit_mask); - } - } + else + { + /*--------------------------------------------------------*\ + ! Remove the coding pass membershib for the current sample ! + ! to clear it for the other coding passes. ! + \*--------------------------------------------------------*/ + stripe[k].pi ^= (stripe[k].pi & bit_mask); + } + } + } + else + { + /*--------------------------------------------------------*\ + ! Remove the coding pass membershib for the current stripe ! + ! to clear it for the other coding passes. ! + \*--------------------------------------------------------*/ + stripe[k].pi = 0; + } } - else - { - stripe[k].pi = 0; - } - } - } + } + /*--------------------------------------------------------*\ + ! Encode the remaining, not fully populated stripe. ! + \*--------------------------------------------------------*/ if(rest < 4) - { - for(x = 0; x < coder->width; ++x, ++k) - { - if((stripe[k].sigma^0xF) & stripe_mask) + { + 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)) - { - 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) + /*--------------------------------------------------------*\ + ! Check if a sample in the current stripe has not yet be- ! + ! come significant. If true, loop over the current stripe ! + ! and evaluate the non-significant sample bits. ! + \*--------------------------------------------------------*/ + if(((stripe[k].sigma^0xF) & stripe_mask) != 0) + { + for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> rest; bit_mask >>= 1) + { + if((stripe[k].sigma & bit_mask) == 0) { - 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; + /*--------------------------------------------------------*\ + ! Evaluate the intermediate sig. context labels for the ! + ! horizontal, vertical and diagonal sample neighbours. ! + \*--------------------------------------------------------*/ + k_h = (stripe[k].stripe_l->sigma & bit_mask) + + (stripe[k].stripe_r->sigma & bit_mask); - if(l == 3) - { - xi_v |= ((0x01 & stripe[k].stripe_u->sigma) | ((0x01 & stripe[k].stripe_u->xi) << 2)); - } + k_v = ((bit_mask & (stripe[k].sigma >> 1)) + + (bit_mask & (stripe[k].sigma << 1))); - 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]); + 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))); - mse += DISTORTION_TS_LUT[((stripe[k].sample[l] >> dist_shift) << dist_corr) & 0x1F]; - stripe[k].sigma |= bit_mask; + /*--------------------------------------------------------*\ + ! Adjust the intermediate context labels in case the sam- ! + ! ple borders with an upper stripe neighbor. ! + \*--------------------------------------------------------*/ + 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; + } + + /*--------------------------------------------------------*\ + ! Calculate the context label for the current sample. If ! + ! the neighborhood is significant (k_sig>0), proceed with ! + ! encoding the sample bit. ! + \*--------------------------------------------------------*/ + k_sig = ((15 * k_h + 5 * k_v + k_d) >> l); + + if(k_sig != 0) + { + /*--------------------------------------------------------*\ + ! Encode the bit for the current sample using the suitable ! + ! context extracted from the sig2context lookup table. If ! + ! the bit is significant, proceed with encoding the sign. ! + \*--------------------------------------------------------*/ + mq_bit_encode(coder->bitcoder, (uchar)((bit >> l) & 0x01), coder->sig2context[k_sig]); + + if((bit & bit_mask) != 0) + { + /*--------------------------------------------------------*\ + ! Evaluate the intermediate net sign bias quantities for ! + ! the horizontal and vertical sample neighbours. ! + \*--------------------------------------------------------*/ + 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; + + /*--------------------------------------------------------*\ + ! Adjust the intermediate net sign bias quantities in case ! + ! the sample borders with an upper neighbor. ! + \*--------------------------------------------------------*/ + if(l == 3) + { + xi_v |= ((0x01 & stripe[k].stripe_u->sigma) | + ((0x01 & stripe[k].stripe_u->xi) << 2)); + } + + /*--------------------------------------------------------*\ + ! Evaluate the sample sign as well as the net sign bias ! + ! quantities. Encode the sample sign using the suitable ! + ! flip factor XI2CONT[*][1] and context XI2CONT[*][0]. ! + \*--------------------------------------------------------*/ + buff = (bit_mask & stripe[k].xi) >> l; + + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + mq_bit_encode(coder->bitcoder, (uchar)(buff^XI2CONT[(xi_h << 2) | xi_v][1]), + XI2CONT[(xi_h << 2) | xi_v][0]); + + /*--------------------------------------------------------*\ + ! Evaluate and add the error of omitting the current bit ! + ! to the coding pass distortion estimation. Additionally, ! + ! set the significance state for the current sample. ! + \*--------------------------------------------------------*/ + buff = (uint8)((stripe[k].sample[l] >> dist_shift) << dist_corr); + mse += DISTORTION_TS_LUT[buff & 0x1F]; + stripe[k].sigma |= bit_mask; + } + /*--------------------------------------------------------*\ + ! Set the coding pass membershib for the current sample to ! + ! remove it from the other coding passes. ! + \*--------------------------------------------------------*/ + stripe[k].pi |= bit_mask; + } } - - stripe[k].pi |= bit_mask; - } - } - else - { - stripe[k].pi ^= (stripe[k].pi & bit_mask); - } - } + else + { + /*--------------------------------------------------------*\ + ! Remove the coding pass membershib for the current sample ! + ! to clear it for the other coding passes. ! + \*--------------------------------------------------------*/ + stripe[k].pi ^= (stripe[k].pi & bit_mask); + } + } + } + else + { + /*--------------------------------------------------------*\ + ! Remove the coding pass membershib for the current stripe ! + ! to clear it for the other coding passes. ! + \*--------------------------------------------------------*/ + stripe[k].pi = 0; + } } - else - { - stripe[k].pi = 0; - } - } - } - } - return mse; + } + } + /*--------------------------------------------------------*\ + ! Return the distortion estimation to the function caller. ! + \*--------------------------------------------------------*/ + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function describes the magnitude refinement encoding pass for a bwc code- ! +! block. This is the second coding pass applied to each bitplane, encoding those ! +! samples that have become significant in a previous coding pass. Specifically, ! +! this coding pass refines the magnitude of previously significant samples. ! +! The magnitude refinement pass is omitted for the most significant bitplane ! +! since no samples have become significant in a previous coding pass. ! +! Concurrently, the function will evaluate and return an estimation for the dis- ! +! tortion incurred if the coding pass is dropped from the final codestream. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! coder bwc_coder* - Structure defining and control- ! +! ling the encoding procedure ! +! for a codeblock. ! +! ! +! b signed int(8 bit) - Bitfield encoded in the cur- ! +! rent coding pass. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uint64 - Distortion estimation for the ! +! current coding pass. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static uint64 -magnitude_refinement_enc_pass(bwc_coder *const coder, const int8 b) +magnitude_refinement_enc_pass(bwc_coder *const coder, + int8 const 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 INT VARIABLES: ! + \*-----------------------*/ + uint64 i, j; + uint64 k, x; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_coder_stripe *stripe; + int64 mse; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(coder); + uint16 k_mag; - 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; + uint8 bit_mask; - for(i = 0, k = 0; i < coder->no_slice; ++i) - { + uint8 dist_shift, dist_corr, l; + + uint8 buff; + + uint8 bit; + uint8 rest; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe *stripe; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + stripe = coder->data; + + /*--------------------------------------------------------*\ + ! Evaluate the number of vert. samples in the last stripe. ! + \*--------------------------------------------------------*/ + rest = 4 - (coder->height & 0x03); + + /*--------------------------------------------------------*\ + ! Evaluate the up (_shift) or down (_corr) shift parame- ! + ! ters used to position a bit of the current bitplane at ! + ! the appropriate 5th position for the dis. lookup tables. ! + \*--------------------------------------------------------*/ + dist_shift = (b < 5) ? 0 : (b - 5); + dist_corr = (b < 5) ? (5 - b) : 0; + + /*--------------------------------------------------------*\ + ! Walk through all stripes in the codeblock and encode all ! + ! bits from samples that have already become significant. ! + \*--------------------------------------------------------*/ + for(i = 0, k = 0, mse = 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) + { + for(x = 0; x < coder->width; ++x, ++k) { - if(sig & bit_mask) - { - k_mag = CONTEXT_MAG; + /*--------------------------------------------------------*\ + ! Loop over the current stripe and evaluate the samples ! + ! that have become significant in a previous bitplane. ! + \*--------------------------------------------------------*/ + for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> 0; bit_mask >>= 1) + { + if(((stripe[k].sigma & (~stripe[k].pi)) & bit_mask) != 0) + { + /*--------------------------------------------------------*\ + ! Initialize the magnitude context label. ! + \*--------------------------------------------------------*/ + 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; - } - } + /*--------------------------------------------------------*\ + ! Adjust the context label if a non-zero magnitude bit has ! + ! already been encoded in a previous bitplane. ! + \*--------------------------------------------------------*/ + if((stripe[k].delta & bit_mask) != 0) + { + k_mag += 2; + } + /*--------------------------------------------------------*\ + ! Adjust the context label if any of the sample neighbors ! + ! are significant. ! + \*--------------------------------------------------------*/ + else + { + if((bit_mask & (stripe[k].stripe_l->sigma >> 1)) || + (bit_mask & stripe[k].stripe_l->sigma) || + (bit_mask & (stripe[k].stripe_l->sigma << 1)) || + (bit_mask & (stripe[k].sigma >> 1)) || + (bit_mask & (stripe[k].sigma << 1)) || + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) || + (bit_mask & stripe[k].stripe_r->sigma) || + (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; + } + } + /*--------------------------------------------------------*\ + ! Encode the bit for the current sample using the suitable ! + ! magnitude context. ! + \*--------------------------------------------------------*/ + mq_bit_encode(coder->bitcoder, (uchar)((bit >> l) & 0x01), k_mag); - bit_encode(coder->bitcoder, (uchar)((bit >> l) & 0x01), k_mag); + /*--------------------------------------------------------*\ + ! Evaluate and add the error of omitting the current bit ! + ! to the coding pass distortion estimation. Additionally, ! + ! set the delayed sig. state for the current sample. ! + \*--------------------------------------------------------*/ + buff = (uint8)((stripe[k].sample[l] >> dist_shift) << dist_corr); + mse += DISTORTION_TM_LUT[buff & 0x3F]; - mse += DISTORTION_TM_LUT[((stripe[k].sample[l] >> dist_shift) << dist_corr) & 0x3F]; - stripe[k].delta |= bit_mask; - } + stripe[k].delta |= bit_mask; + } + } } - } - } + } + /*--------------------------------------------------------*\ + ! Encode the remaining, not fully populated stripe. ! + \*--------------------------------------------------------*/ if(rest < 4) - { - for(x = 0; x < coder->width; ++x, ++k) - { - sig = (stripe[k].sigma & (~stripe[k].pi)) & stripe_mask; + { + for(x = 0; x < coder->width; ++x, ++k) + { + /*--------------------------------------------------------*\ + ! Loop over the current stripe and evaluate the samples ! + ! that have become significant in a previous bitplane. ! + \*--------------------------------------------------------*/ + for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> rest; bit_mask >>= 1) + { + if(((stripe[k].sigma & (~stripe[k].pi)) & bit_mask) == 0) + { + /*--------------------------------------------------------*\ + ! Initialize the magnitude context label. ! + \*--------------------------------------------------------*/ + k_mag = CONTEXT_MAG; - for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> rest; bit_mask >>= 1) - { - if(sig & bit_mask) - { - k_mag = CONTEXT_MAG; + /*--------------------------------------------------------*\ + ! Adjust the context label if a non-zero magnitude bit has ! + ! already been encoded in a previous bitplane. ! + \*--------------------------------------------------------*/ + if((stripe[k].delta & bit_mask) != 0) + { + k_mag += 2; + } + /*--------------------------------------------------------*\ + ! Adjust the context label if any of the sample neighbors ! + ! are significant. ! + \*--------------------------------------------------------*/ + else + { + if((bit_mask & (stripe[k].stripe_l->sigma >> 1)) || + (bit_mask & stripe[k].stripe_l->sigma) || + (bit_mask & (stripe[k].stripe_l->sigma << 1)) || + (bit_mask & (stripe[k].sigma >> 1)) || + (bit_mask & (stripe[k].sigma << 1)) || + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) || + (bit_mask & stripe[k].stripe_r->sigma) || + (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; + } + } + /*--------------------------------------------------------*\ + ! Encode the bit for the current sample using the suitable ! + ! magnitude context. ! + \*--------------------------------------------------------*/ + mq_bit_encode(coder->bitcoder, (uchar)((bit >> l) & 0x01), k_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; - } - } + /*--------------------------------------------------------*\ + ! Evaluate and add the error of omitting the current bit ! + ! to the coding pass distortion estimation. Additionally, ! + ! set the delayed sig. state for the current sample. ! + \*--------------------------------------------------------*/ + buff = (uint8)((stripe[k].sample[l] >> dist_shift) << dist_corr); + mse += DISTORTION_TM_LUT[buff & 0x3F]; - 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; - } + stripe[k].delta |= bit_mask; + } + } } - } - } - } - return mse; + } + } + /*--------------------------------------------------------*\ + ! Return the distortion estimation to the function caller. ! + \*--------------------------------------------------------*/ + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function describes the cleanup encoding pass for a bwc codeblock. This is ! +! the third coding pass applied to each bitplane, encoding the remaining samples ! +! in the current bitplane that have not been encoded by the significance propaga- ! +! tion or magnitude refinement pass. ! +! The cleanup pass is the first and only coding pass applied to the most signifi- ! +! cant bitplane. ! +! Concurrently, the function will evaluate and return an estimation for the dis- ! +! tortion incurred if the coding pass is dropped from the final codestream. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! coder bwc_coder* - Structure defining and control- ! +! ling the encoding procedure ! +! for a codeblock. ! +! ! +! b signed int(8 bit) - Bitfield encoded in the cur- ! +! rent coding pass. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uint64 - Distortion estimation for the ! +! current coding pass. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static uint64 -cleanup_enc_pass(bwc_coder *const coder, const int8 b) +cleanup_enc_pass(bwc_coder *const coder, + int8 const 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 INT VARIABLES: ! + \*-----------------------*/ + uint64 i, j; + uint64 k, x; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_coder_stripe *stripe; + int64 mse; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(coder); + uint16 k_h, k_v, k_d; + uint16 k_sig; - 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; + uint16 xi_h, xi_v; - for(i = 0, k = 0; i < coder->no_slice; ++i) - { + uint8 bit_mask, l; + + uint8 dist_shift, dist_corr; + + uint8 buff; + + uint8 bit, rest; + + int8 r; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe *stripe; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + stripe = coder->data; + + /*--------------------------------------------------------*\ + ! Evaluate the number of vert. samples in the last stripe ! + \*--------------------------------------------------------*/ + rest = 4 - (coder->height & 0x03); + + /*--------------------------------------------------------*\ + ! Evaluate the up (_shift) or down (_corr) shift parame- ! + ! ters used to position a bit of the current bitplane at ! + ! the appropriate 5th position for the dis. lookup tables. ! + \*--------------------------------------------------------*/ + dist_shift = (b < 5) ? 0 : (b - 5); + dist_corr = (b < 5) ? (5 - b) : 0; + + /*--------------------------------------------------------*\ + ! Walk through all stripes in the codeblock and encode all ! + ! sample bits that have not yet been encoded in the cur- ! + ! rent bitplane. ! + \*--------------------------------------------------------*/ + for(i = 0, k = 0, mse = 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) + { + for(x = 0; x < coder->width; ++x, ++k) { - 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--; - } + /*--------------------------------------------------------*\ + ! Check that the neighborhood of the current stripe is not ! + ! significant. If true, proceed with run coding. If not, ! + ! set r to -1 and continue in the normal encoding mode. ! + \*--------------------------------------------------------*/ + if(((stripe[k].stripe_u->stripe_l->sigma & 0x01) == 0) && + ((stripe[k].stripe_u->sigma & 0x01) == 0) && + ((stripe[k].stripe_u->stripe_r->sigma & 0x01) == 0) && + ((stripe[k].stripe_l->sigma) == 0) && + ((stripe[k].sigma) == 0) && + ((stripe[k].stripe_r->sigma) == 0) && + ((stripe[k].stripe_d->stripe_l->sigma & 0x08) == 0) && + ((stripe[k].stripe_d->sigma & 0x08) == 0) && + ((stripe[k].stripe_d->stripe_r->sigma & 0x08) == 0)) + { + /*--------------------------------------------------------*\ + ! If the current stripe is populated by non-significant ! + ! bits (= 0), set the run coding length to 4 and encode ! + ! the appropriate run coding symbol. ! + \*--------------------------------------------------------*/ + if(stripe[k].bit[b] == 0) + { + r = 4; + mq_bit_encode(coder->bitcoder, (uchar)0, CONTEXT_RUN); + } + /*--------------------------------------------------------*\ + ! If the current stripe is populated by significant bits ! + ! (= 1), set the run length to the index of the first sig. ! + ! bit and encode the run length and interrupt symbol. ! + \*--------------------------------------------------------*/ else - { - k_h = (stripe[k].stripe_l->sigma & bit_mask) + (stripe[k].stripe_r->sigma & bit_mask); + { + r = stripe[k].bit[b] | (stripe[k].bit[b] >> 1); + r |= r >> 2; + r = LEADING_ZERO[r]; - 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) + mq_bit_encode(coder->bitcoder, (uchar)1, CONTEXT_RUN); + mq_bit_encode(coder->bitcoder, (uchar)r >> 1, CONTEXT_UNI); + mq_bit_encode(coder->bitcoder, (uchar)r&0x01, CONTEXT_UNI); + } + } + else + { + r = -1; + } + /*--------------------------------------------------------*\ + ! Loop over the current stripe and evaluate the samples ! + ! that have not become significant in this or any previous ! + ! bitplane. ! + \*--------------------------------------------------------*/ + for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> 0; bit_mask >>= 1) + { + if((bit_mask & stripe[k].sigma) == 0 && + (bit_mask & stripe[k].pi) == 0) + { + /*--------------------------------------------------------*\ + ! Skip all the samples that have already been encoded us- ! + ! ing run coding. ! + \*--------------------------------------------------------*/ + if(r >= 0) { - stripe[k].bit[b] |= (bit << l); + r--; + } + else + { + /*--------------------------------------------------------*\ + ! Evaluate the intermediate sig. context labels for the ! + ! horizontal, vertical and diagonal sample neighbours. ! + \*--------------------------------------------------------*/ + k_h = (bit_mask & stripe[k].stripe_l->sigma) + + (bit_mask & stripe[k].stripe_r->sigma); - 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; + k_v = (bit_mask & (stripe[k].sigma >> 1)) + + (bit_mask & (stripe[k].sigma << 1)); - 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)); - } + 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))); - xi_h = SIG2XI[xi_h]; - xi_v = SIG2XI[xi_v]; + /*--------------------------------------------------------*\ + ! Adjust the intermediate context labels in case the sam- ! + ! ple borders with an upper or lower stripe neighbor. ! + \*--------------------------------------------------------*/ + 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; + } + /*--------------------------------------------------------*\ + ! Calculate the context label and encode the bit for the ! + ! current sample. If the bit is significant, proceed with ! + ! encoding the sign bit. ! + \*--------------------------------------------------------*/ + k_sig = ((15 * k_h + 5 * k_v + k_d) >> l); - stripe[k].xi |= ((XI2CONT[(xi_h << 2) | xi_v][1] ^ bit_decode(coder->bitcoder, XI2CONT[(xi_h << 2) | xi_v][0])) << l); + mq_bit_encode(coder->bitcoder, (uchar)((bit >> l) & 0x01), coder->sig2context[k_sig]); + } + if((bit_mask & bit) != 0) + { + /*--------------------------------------------------------*\ + ! Evaluate the intermediate net sign bias quantities for ! + ! the horizontal and vertical sample neighbours. ! + \*--------------------------------------------------------*/ + 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; - stripe[k].sigma |= bit_mask; + 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; + + /*--------------------------------------------------------*\ + ! Adjust the intermediate net sign bias quantities in case ! + ! the sample borders with an upper or lower neighbor. ! + \*--------------------------------------------------------*/ + 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)); + } + /*--------------------------------------------------------*\ + ! Evaluate the sample sign as well as the net sign bias ! + ! quantities. Encode the sample sign using the suitable ! + ! flip factor XI2CONT[*][1] and context XI2CONT[*][0]. ! + \*--------------------------------------------------------*/ + buff = (bit_mask & stripe[k].xi) >> l; + + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + mq_bit_encode(coder->bitcoder, (uchar)(buff^XI2CONT[(xi_h << 2) | xi_v][1]), + XI2CONT[(xi_h << 2) | xi_v][0]); + + /*--------------------------------------------------------*\ + ! Evaluate and add the error of omitting the current bit ! + ! to the coding pass distortion estimation. Additionally, ! + ! set the delayed sig. state for the current sample. ! + \*--------------------------------------------------------*/ + buff = (uint8)((stripe[k].sample[l] >> dist_shift) << dist_corr); + mse += DISTORTION_TS_LUT[buff & 0x1F]; + + stripe[k].sigma |= bit_mask; + } + } + } + } + } + /*--------------------------------------------------------*\ + ! Encode the remaining, not fully populated stripe. ! + \*--------------------------------------------------------*/ + if(rest < 4) + { + for(x = 0; x < coder->width; ++x, ++k) + { + /*--------------------------------------------------------*\ + ! Loop over the current stripe and evaluate the samples ! + ! that have not become significant in this or any previous ! + ! bitplane. ! + \*--------------------------------------------------------*/ + for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> rest; bit_mask >>= 1) + { + if(((bit_mask & stripe[k].sigma) == 0) && + ((bit_mask & stripe[k].pi) == 0)) + { + /*--------------------------------------------------------*\ + ! Evaluate the intermediate sig. context labels for the ! + ! horizontal, vertical and diagonal sample neighbours. ! + \*--------------------------------------------------------*/ + k_h = (bit_mask & stripe[k].stripe_l->sigma) + + (bit_mask & stripe[k].stripe_r->sigma); + + 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))); + + /*--------------------------------------------------------*\ + ! Adjust the intermediate context labels in case the sam- ! + ! ple borders with an upper stripe neighbor. ! + \*--------------------------------------------------------*/ + 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; } - stripe[k].pi |= bit_mask; - } - } - else - { - stripe[k].pi ^= (stripe[k].pi & bit_mask); - } - } - } - else - { - stripe[k].pi = 0; - } - } - } + /*--------------------------------------------------------*\ + ! Calculate the context label and encode the bit for the ! + ! current sample. If the bit is significant, proceed with ! + ! encoding the sign bit. ! + \*--------------------------------------------------------*/ + k_sig = ((15 * k_h + 5 * k_v + k_d) >> l); - 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); + mq_bit_encode(coder->bitcoder, (uchar)((bit >> l) & 0x01), coder->sig2context[k_sig]); - 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) + if((bit_mask & bit) != 0) { - stripe[k].bit[b] |= (bit << l); + /*--------------------------------------------------------*\ + ! Evaluate the intermediate net sign bias quantities for ! + ! the horizontal and vertical sample neighbours. ! + \*--------------------------------------------------------*/ + 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_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; + 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)); - } + /*--------------------------------------------------------*\ + ! Adjust the intermediate net sign bias quantities in case ! + ! the sample borders with an upper neighbor. ! + \*--------------------------------------------------------*/ + if(l == 3) + { + xi_v |= ((0x01 & stripe[k].stripe_u->sigma) | + ((0x01 & stripe[k].stripe_u->xi) << 2)); + } + /*--------------------------------------------------------*\ + ! Evaluate the sample sign as well as the net sign bias ! + ! quantities. Encode the sample sign using the suitable ! + ! flip factor XI2CONT[*][1] and context XI2CONT[*][0]. ! + \*--------------------------------------------------------*/ + buff = (bit_mask & stripe[k].xi) >> l; - 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); + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; - stripe[k].sigma |= bit_mask; + mq_bit_encode(coder->bitcoder, (uchar)(buff^XI2CONT[(xi_h << 2) | xi_v][1]), + XI2CONT[(xi_h << 2) | xi_v][0]); + + /*--------------------------------------------------------*\ + ! Evaluate and add the error of omitting the current bit ! + ! to the coding pass distortion estimation. Additionally, ! + ! set the delayed sig. state for the current sample. ! + \*--------------------------------------------------------*/ + buff = (uint8)((stripe[k].sample[l] >> dist_shift) << dist_corr); + mse += DISTORTION_TS_LUT[buff & 0x1F]; + + stripe[k].sigma |= bit_mask; + } + } + } + } + } + } + /*--------------------------------------------------------*\ + ! Return the distortion estimation to the function caller. ! + \*--------------------------------------------------------*/ + return mse; +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function describes the significance propagation decoding pass for a bwc ! +! codeblock. This is the first coding pass applied to each bitplane, decoding ! +! those samples that have a significant neighborhood - at least one of its neigh- ! +! bors is significant. Specifically, this coding pass decodes those samples that ! +! are most likely to become significant in the current bitplane b. ! +! The significance propagation pass is omitted for the most significant bitplane, ! +! since no samples have a significant neighborhood, yet. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! coder bwc_coder* - Structure defining and control- ! +! ling the encoding procedure ! +! for a codeblock. ! +! ! +! b signed int(8 bit) - Bitfield encoded in the cur- ! +! rent coding pass. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static void +significance_propagation_dec_pass(bwc_coder *const coder, + int8 const 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 buff; + + uint8 l; + + uint8 bit, rest; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe *stripe; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + stripe = coder->data; + + /*--------------------------------------------------------*\ + ! Evaluate if the number of vertical samples is divisable ! + ! by 4 and set up an appropriate mask for the last, not ! + ! fully populated, stripe. ! + \*--------------------------------------------------------*/ + stripe_mask = ~((0x0F >> ((coder->height & 0x03))) | 0xF0); + rest = 4 - (coder->height & 0x03); + + /*--------------------------------------------------------*\ + ! Walk through all stripes in the codeblock and decode all ! + ! the sample bits with a significant neighborhood. ! + \*--------------------------------------------------------*/ + 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) + { + /*--------------------------------------------------------*\ + ! Check if a sample in the current stripe has not yet be- ! + ! come significant. If true, loop over the current stripe ! + ! and evaluate the non-significant sample bits. ! + \*--------------------------------------------------------*/ + if((stripe[k].sigma^0xF) != 0) + { + for(bit_mask = 0x08, l = 4; l --> 0; bit_mask >>= 1) + { + if((bit_mask & stripe[k].sigma) == 0) + { + /*--------------------------------------------------------*\ + ! Evaluate the intermediate sig. context labels for the ! + ! horizontal, vertical and diagonal sample neighbours. ! + \*--------------------------------------------------------*/ + k_h = (bit_mask & stripe[k].stripe_l->sigma) + + (bit_mask & stripe[k].stripe_r->sigma); + + 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))); + + /*--------------------------------------------------------*\ + ! Adjust the intermediate context labels in case the sam- ! + ! ple borders with an upper or lower stripe neighbor. ! + \*--------------------------------------------------------*/ + 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; + } + /*--------------------------------------------------------*\ + ! Calculate the context label for the current sample. If ! + ! the neighborhood is significant (k_sig>0), proceed with ! + ! decoding the sample bit. ! + \*--------------------------------------------------------*/ + k_sig = ((15 * k_h + 5 * k_v + k_d) >> l); + + if(k_sig != 0) + { + /*--------------------------------------------------------*\ + ! Decode the bit for the current sample using the suitable ! + ! context extracted from the sig2context lookup table. If ! + ! the bit is significant, proceed with decoding the sign. ! + \*--------------------------------------------------------*/ + bit = mq_bit_decode(coder->bitcoder, coder->sig2context[k_sig]); + + if(bit != 0) + { + /*--------------------------------------------------------*\ + ! Set the significant bit in the coder stripe structure. ! + \*--------------------------------------------------------*/ + stripe[k].bit[b] |= (bit << l); + + /*--------------------------------------------------------*\ + ! Evaluate the intermediate net sign bias quantities for ! + ! the horizontal and vertical sample neighbours. ! + \*--------------------------------------------------------*/ + 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; + + /*--------------------------------------------------------*\ + ! Adjust the intermediate net sign bias quantities in case ! + ! the sample borders with an upper or lower neighbor. ! + \*--------------------------------------------------------*/ + 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)); + } + /*--------------------------------------------------------*\ + ! Evaluate the net sign bias quantities and decode the sam-! + ! ple sign using the suitable context XI2CONT[*][0]. ! + \*--------------------------------------------------------*/ + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + buff = mq_bit_decode(coder->bitcoder, XI2CONT[(xi_h << 2) | xi_v][0]); + + /*--------------------------------------------------------*\ + ! Set the sign and sig. state for the current sample. ! + \*--------------------------------------------------------*/ + stripe[k].xi |= ((XI2CONT[(xi_h << 2) | xi_v][1] ^ buff) << l); + stripe[k].sigma |= bit_mask; + } + /*--------------------------------------------------------*\ + ! Set the coding pass membershib for the current sample to ! + ! remove it from the other coding passes. ! + \*--------------------------------------------------------*/ + stripe[k].pi |= bit_mask; + } + } + else + { + /*--------------------------------------------------------*\ + ! Remove the coding pass membershib for the current sample ! + ! to clear it for the other coding passes. ! + \*--------------------------------------------------------*/ + stripe[k].pi ^= (stripe[k].pi & bit_mask); + } + } + } + else + { + /*--------------------------------------------------------*\ + ! Remove the coding pass membershib for the current stripe ! + ! to clear it for the other coding passes. ! + \*--------------------------------------------------------*/ + stripe[k].pi = 0; + } + } + } + /*--------------------------------------------------------*\ + ! Encode the remaining, not fully populated stripe. ! + \*--------------------------------------------------------*/ + if(rest < 4) + { + for(x = 0; x < coder->width; ++x, ++k) + { + /*--------------------------------------------------------*\ + ! Check if a sample in the current stripe has not yet be- ! + ! come significant. If true, loop over the current stripe ! + ! and evaluate the non-significant sample bits. ! + \*--------------------------------------------------------*/ + if(((stripe[k].sigma^0xF) & stripe_mask) != 0) + { + for(bit = stripe[k].bit[b], bit_mask = 0x08, l = 4; l --> rest; bit_mask >>= 1) + { + if((bit_mask & stripe[k].sigma) == 0) + { + /*--------------------------------------------------------*\ + ! Evaluate the intermediate sig. context labels for the ! + ! horizontal, vertical and diagonal sample neighbours. ! + \*--------------------------------------------------------*/ + k_h = (bit_mask & stripe[k].stripe_l->sigma) + + (bit_mask & stripe[k].stripe_r->sigma); + + 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))); + + /*--------------------------------------------------------*\ + ! Adjust the intermediate context labels in case the sam- ! + ! ple borders with an upper stripe neighbor. ! + \*--------------------------------------------------------*/ + 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; + } + /*--------------------------------------------------------*\ + ! Calculate the context label for the current sample. If ! + ! the neighborhood is significant (k_sig>0), proceed with ! + ! decoding the sample bit. ! + \*--------------------------------------------------------*/ + k_sig = ((15 * k_h + 5 * k_v + k_d) >> l); + + if(k_sig != 0) + { + /*--------------------------------------------------------*\ + ! Decode the bit for the current sample using the suitable ! + ! context extracted from the sig2context lookup table. If ! + ! the bit is significant, proceed with decoding the sign. ! + \*--------------------------------------------------------*/ + bit = mq_bit_decode(coder->bitcoder, coder->sig2context[k_sig]); + + if(bit != 0) + { + /*--------------------------------------------------------*\ + ! Set the significant bit in the coder stripe structure. ! + \*--------------------------------------------------------*/ + stripe[k].bit[b] |= (bit << l); + + /*--------------------------------------------------------*\ + ! Evaluate the intermediate net sign bias quantities for ! + ! the horizontal and vertical sample neighbours. ! + \*--------------------------------------------------------*/ + 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; + + /*--------------------------------------------------------*\ + ! Adjust the intermediate net sign bias quantities in case ! + ! the sample borders with an upper neighbor. ! + \*--------------------------------------------------------*/ + if(l == 3) + { + xi_v |= ((0x01 & stripe[k].stripe_u->sigma) | + ((0x01 & stripe[k].stripe_u->xi) << 2)); + } + /*--------------------------------------------------------*\ + ! Evaluate the net sign bias quantities and decode the sam-! + ! ple sign using the suitable context XI2CONT[*][0]. ! + \*--------------------------------------------------------*/ + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + buff = mq_bit_decode(coder->bitcoder, XI2CONT[(xi_h << 2) | xi_v][0]); + + /*--------------------------------------------------------*\ + ! Set the sign and sig. state for the current sample. ! + \*--------------------------------------------------------*/ + stripe[k].xi |= ((XI2CONT[(xi_h << 2) | xi_v][1] ^ buff) << l); + stripe[k].sigma |= bit_mask; + } + /*--------------------------------------------------------*\ + ! Set the coding pass membershib for the current sample to ! + ! remove it from the other coding passes. ! + \*--------------------------------------------------------*/ + stripe[k].pi |= bit_mask; + } + } + else + { + /*--------------------------------------------------------*\ + ! Remove the coding pass membershib for the current sample ! + ! to clear it for the other coding passes. ! + \*--------------------------------------------------------*/ + stripe[k].pi ^= (stripe[k].pi & bit_mask); + } + } + } + else + { + /*--------------------------------------------------------*\ + ! Remove the coding pass membershib for the current stripe ! + ! to clear it for the other coding passes. ! + \*--------------------------------------------------------*/ + stripe[k].pi = 0; + } + } + } + } +} + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function describes the magnitude refinement decoding pass for a bwc code- ! +! block. This is the second coding pass applied to each bitplane, decoding those ! +! samples that have become significant in a previous coding pass. Specifically, ! +! this coding pass refines the magnitude of previously significant samples. ! +! The magnitude refinement pass is omitted for the most significant bitplane ! +! since no samples have become significant in a previous coding pass. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! coder bwc_coder* - Structure defining and control- ! +! ling the encoding procedure ! +! for a codeblock. ! +! ! +! b signed int(8 bit) - Bitfield encoded in the cur- ! +! rent coding pass. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static void +magnitude_refinement_dec_pass(bwc_coder *const coder, + int8 const b) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 i, j; + uint64 k, x; + + uint16 k_mag; + + uint8 bit_mask; + + uint8 l; + + uint8 rest; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe *stripe; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + stripe = coder->data; + + /*--------------------------------------------------------*\ + ! Evaluate the number of vert. samples in the last stripe. ! + \*--------------------------------------------------------*/ + rest = 4 - (coder->height & 0x03); + + /*--------------------------------------------------------*\ + ! Walk through all stripes in the codeblock and decode all ! + ! bits from samples that have already become significant. ! + \*--------------------------------------------------------*/ + 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) + { + /*--------------------------------------------------------*\ + ! Loop over the current stripe and evaluate the samples ! + ! that have become significant in a previous bitplane. ! + \*--------------------------------------------------------*/ + for(bit_mask = 0x08, l = 4; l --> 0; bit_mask >>= 1) + { + if(((stripe[k].sigma & (~stripe[k].pi)) & bit_mask) != 0) + { + /*--------------------------------------------------------*\ + ! Initialize the magnitude context label. ! + \*--------------------------------------------------------*/ + k_mag = CONTEXT_MAG; + + /*--------------------------------------------------------*\ + ! Adjust the context label if a non-zero magnitude bit has ! + ! already been decoded in a previous bitplane. ! + \*--------------------------------------------------------*/ + if((stripe[k].delta & bit_mask) != 0) + { + k_mag += 2; + } + /*--------------------------------------------------------*\ + ! Adjust the context label if any of the sample neighbors ! + ! are significant. ! + \*--------------------------------------------------------*/ + else + { + if((bit_mask & (stripe[k].stripe_l->sigma >> 1)) || + (bit_mask & stripe[k].stripe_l->sigma) || + (bit_mask & (stripe[k].stripe_l->sigma << 1)) || + (bit_mask & (stripe[k].sigma >> 1)) || + (bit_mask & (stripe[k].sigma << 1)) || + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) || + (bit_mask & stripe[k].stripe_r->sigma) || + (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; + } + } + /*--------------------------------------------------------*\ + ! Decode the bit for the current sample using the suitable ! + ! magnitude context, store it in the appropriate bitplane ! + ! and set the delayed sig. state for the current sample. ! + \*--------------------------------------------------------*/ + stripe[k].bit[b] |= (mq_bit_decode(coder->bitcoder, k_mag) << l); + stripe[k].delta |= bit_mask; + } + } + } + } + /*--------------------------------------------------------*\ + ! Encode the remaining, not fully populated stripe. ! + \*--------------------------------------------------------*/ + if(rest < 4) + { + for(x = 0; x < coder->width; ++x, ++k) + { + /*--------------------------------------------------------*\ + ! Loop over the current stripe and evaluate the samples ! + ! that have become significant in a previous bitplane. ! + \*--------------------------------------------------------*/ + for(bit_mask = 0x08, l = 4; l --> rest; bit_mask >>= 1) + { + if(((stripe[k].sigma & (~stripe[k].pi)) & bit_mask) != 0) + { + /*--------------------------------------------------------*\ + ! Initialize the magnitude context label. ! + \*--------------------------------------------------------*/ + k_mag = CONTEXT_MAG; + + /*--------------------------------------------------------*\ + ! Adjust the context label if a non-zero magnitude bit has ! + ! already been decoded in a previous bitplane. ! + \*--------------------------------------------------------*/ + if((stripe[k].delta & bit_mask) != 0) + { + k_mag += 2; + } + /*--------------------------------------------------------*\ + ! Adjust the context label if any of the sample neighbors ! + ! are significant. ! + \*--------------------------------------------------------*/ + else + { + if((bit_mask & (stripe[k].stripe_l->sigma >> 1)) || + (bit_mask & stripe[k].stripe_l->sigma) || + (bit_mask & (stripe[k].stripe_l->sigma << 1)) || + (bit_mask & (stripe[k].sigma >> 1)) || + (bit_mask & (stripe[k].sigma << 1)) || + (bit_mask & (stripe[k].stripe_r->sigma >> 1)) || + (bit_mask & stripe[k].stripe_r->sigma) || + (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].pi |= bit_mask; - } - } - else - { - stripe[k].pi ^= (stripe[k].pi & bit_mask); - } - } + /*--------------------------------------------------------*\ + ! Decode the bit for the current sample using the suitable ! + ! magnitude context, store it in the appropriate bitplane ! + ! and set the delayed sig. state for the current sample. ! + \*--------------------------------------------------------*/ + stripe[k].bit[b] |= (mq_bit_decode(coder->bitcoder, k_mag) << l); + stripe[k].delta |= 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function describes the cleanup decoding pass for a bwc codeblock. This is ! +! the third coding pass applied to each bitplane, decoding the remaining samples ! +! in the current bitplane that have not been decoded by the significance propaga- ! +! tion or magnitude refinement pass. ! +! The cleanup pass is the first and only coding pass applied to the most signifi- ! +! cant bitplane. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! coder bwc_coder* - Structure defining and control- ! +! ling the encoding procedure ! +! for a codeblock. ! +! ! +! b signed int(8 bit) - Bitfield encoded in the cur- ! +! rent coding pass. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -magnitude_refinement_dec_pass(bwc_coder *const coder, const int8 b) +cleanup_dec_pass(bwc_coder *const coder, + int8 const 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 INT VARIABLES: ! + \*-----------------------*/ + uint64 i, j; + uint64 k, x; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_coder_stripe *stripe; + uint16 k_h, k_v, k_d; + uint16 k_sig; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(coder); + uint16 xi_h, xi_v; - stripe = coder->data; - stripe_mask= ~((0x0F >> ((coder->height & 0x03))) | 0xF0); - rest = 4 - (coder->height & 0x03); + uint8 bit_mask, l; - for(i = 0, k = 0; i < coder->no_slice; ++i) - { + uint8 buff; + + uint8 bit, rest; + + int8 r; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_coder_stripe *stripe; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(coder); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + stripe = coder->data; + + /*--------------------------------------------------------*\ + ! Evaluate the number of vert. samples in the last stripe ! + \*--------------------------------------------------------*/ + rest = 4 - (coder->height & 0x03); + + /*--------------------------------------------------------*\ + ! Walk through all stripes in the codeblock and decode all ! + ! sample bits that have not yet been decoded in the cur- ! + ! rent bitplane. ! + \*--------------------------------------------------------*/ + 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) + { + for(x = 0, bit = 0; x < coder->width; ++x, ++k) { - if(sig & bit_mask) - { - k_mag = CONTEXT_MAG; - - if(stripe[k].delta & bit_mask) - { - k_mag += 2; - } + /*--------------------------------------------------------*\ + ! Check that the neighborhood of the current stripe is not ! + ! significant. If true, proceed with run coding. If not, ! + ! set r to -1 and continue in the normal decoding mode. ! + \*--------------------------------------------------------*/ + if(((stripe[k].stripe_u->stripe_l->sigma & 0x01) == 0) && + ((stripe[k].stripe_u->sigma & 0x01) == 0) && + ((stripe[k].stripe_u->stripe_r->sigma & 0x01) == 0) && + ((stripe[k].stripe_l->sigma) == 0) && + ((stripe[k].sigma) == 0) && + ((stripe[k].stripe_r->sigma) == 0) && + ((stripe[k].stripe_d->stripe_l->sigma & 0x08) == 0) && + ((stripe[k].stripe_d->sigma & 0x08) == 0) && + ((stripe[k].stripe_d->stripe_r->sigma & 0x08) == 0)) + { + /*--------------------------------------------------------*\ + ! Decode the next bit from the bitstream using the run co- ! + ! ding context. If no run coding interrupt symbol has been ! + ! encoded (bit = 1), set the run coding length to 4. ! + \*--------------------------------------------------------*/ + if(mq_bit_decode(coder->bitcoder, CONTEXT_RUN) == 0) + { + r = 4; + } + /*--------------------------------------------------------*\ + ! If a run coding interrupt (bit = 1) has been encoded, ! + ! decode the index of the first significant bit. ! + \*--------------------------------------------------------*/ 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; - } - } + { + r = mq_bit_decode(coder->bitcoder, CONTEXT_UNI); + r = (r << 1) + mq_bit_decode(coder->bitcoder, CONTEXT_UNI); + bit |= (0x08 >> r); + } + } + else + { + r = -1; + } + /*--------------------------------------------------------*\ + ! Loop over the current stripe and evaluate the samples ! + ! that have not become significant in this or any previous ! + ! bitplane. ! + \*--------------------------------------------------------*/ + for(bit_mask = 0x08, l = 4; l --> 0; bit_mask >>= 1) + { + if((bit_mask & stripe[k].sigma) == 0 && + (bit_mask & stripe[k].pi) == 0) + { + /*--------------------------------------------------------*\ + ! Skip the samples that had been encoded using run coding. ! + \*--------------------------------------------------------*/ + if(r >= 0) + { + r--; + } + else + { + /*--------------------------------------------------------*\ + ! Evaluate the intermediate sig. context labels for the ! + ! horizontal, vertical and diagonal sample neighbours. ! + \*--------------------------------------------------------*/ + k_h = (bit_mask & stripe[k].stripe_l->sigma ) + + (bit_mask & stripe[k].stripe_r->sigma ); - stripe[k].bit[b] |= (bit_decode(coder->bitcoder, k_mag) << l); + k_v = (bit_mask & (stripe[k].sigma >> 1)) + + (bit_mask & (stripe[k].sigma << 1)); - stripe[k].delta |= bit_mask; - } + 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))); + + /*--------------------------------------------------------*\ + ! Adjust the intermediate context labels in case the sam- ! + ! ple borders with an upper or lower stripe neighbor. ! + \*--------------------------------------------------------*/ + 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; + } + /*--------------------------------------------------------*\ + ! Calculate the context label and decode the bit for the ! + ! current sample. If the bit is significant, proceed with ! + ! decoding the sign bit. ! + \*--------------------------------------------------------*/ + k_sig = ((15 * k_h + 5 * k_v + k_d) >> l); + + bit |= (mq_bit_decode(coder->bitcoder, coder->sig2context[k_sig]) << l); + } + if((bit & bit_mask) != 0) + { + /*--------------------------------------------------------*\ + ! Evaluate the intermediate net sign bias quantities for ! + ! the horizontal and vertical sample neighbours. ! + \*--------------------------------------------------------*/ + 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; + + /*--------------------------------------------------------*\ + ! Adjust the intermediate net sign bias quantities in case ! + ! the sample borders with an upper or lower neighbor. ! + \*--------------------------------------------------------*/ + 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)); + } + /*--------------------------------------------------------*\ + ! Evaluate the net sign bias quantities and decode the sam-! + ! ple sign using the suitable context XI2CONT[*][0]. ! + \*--------------------------------------------------------*/ + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + buff = mq_bit_decode(coder->bitcoder, XI2CONT[(xi_h << 2) | xi_v][0]); + + /*--------------------------------------------------------*\ + ! Set the sign and sig. state for the current sample. ! + \*--------------------------------------------------------*/ + stripe[k].xi |= ((XI2CONT[(xi_h << 2) | xi_v][1] ^ buff) << l); + stripe[k].sigma |= bit_mask; + } + } + } + /*--------------------------------------------------------*\ + ! Set the significant bit in the coder stripe structure. ! + \*--------------------------------------------------------*/ + stripe[k].bit[b] |= bit; } - } - } - + } + /*--------------------------------------------------------*\ + ! Decode the remaining, not fully populated stripe. ! + \*--------------------------------------------------------*/ if(rest < 4) - { - for(x = 0; x < coder->width; ++x, ++k) - { - sig = (stripe[k].sigma & (~stripe[k].pi)) & stripe_mask; + { + for(x = 0, bit = 0; x < coder->width; ++x, ++k) + { + /*--------------------------------------------------------*\ + ! Loop over the current stripe and evaluate the samples ! + ! that have not become significant in this or any previous ! + ! bitplane. ! + \*--------------------------------------------------------*/ + for(bit_mask = 0x08, l = 4; l --> rest; bit_mask >>= 1) + { + if((bit_mask & stripe[k].sigma) == 0 && + (bit_mask & stripe[k].pi) == 0) + { + /*--------------------------------------------------------*\ + ! Evaluate the intermediate sig. context labels for the ! + ! horizontal, vertical and diagonal sample neighbours. ! + \*--------------------------------------------------------*/ + k_h = (bit_mask & stripe[k].stripe_l->sigma) + + (bit_mask & stripe[k].stripe_r->sigma); - for(bit_mask = 0x08, l = 4; l --> rest; bit_mask >>= 1) - { - if(sig & bit_mask) - { - k_mag = CONTEXT_MAG; + k_v = (bit_mask & (stripe[k].sigma >> 1)) + + (bit_mask & (stripe[k].sigma << 1)); - 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; - } - } + 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))); - stripe[k].bit[b] |= (bit_decode(coder->bitcoder, k_mag) << l); + /*--------------------------------------------------------*\ + ! Adjust the intermediate context labels in case the sam- ! + ! ple borders with an upper or lower stripe neighbor. ! + \*--------------------------------------------------------*/ + 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; + } - stripe[k].delta |= bit_mask; - } + /*--------------------------------------------------------*\ + ! Calculate the context label and decode the bit for the ! + ! current sample. If the bit is significant, proceed with ! + ! decoding the sign bit. ! + \*--------------------------------------------------------*/ + k_sig = (15 * k_h + 5 * k_v + k_d) >> l; + + bit |= (mq_bit_decode(coder->bitcoder, coder->sig2context[buff]) << l); + + if((bit & bit_mask) != 0) + { + /*--------------------------------------------------------*\ + ! Evaluate the intermediate net sign bias quantities for ! + ! the horizontal and vertical sample neighbours. ! + \*--------------------------------------------------------*/ + 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; + + /*--------------------------------------------------------*\ + ! Adjust the intermediate net sign bias quantities in case ! + ! the sample borders with an upper neighbor. ! + \*--------------------------------------------------------*/ + if(l == 3) + { + xi_v |= ((0x01 & stripe[k].stripe_u->sigma) | + ((0x01 & stripe[k].stripe_u->xi) << 2)); + } + /*--------------------------------------------------------*\ + ! Evaluate the net sign bias quantities and decode the sam-! + ! ple sign using the suitable context XI2CONT[*][0]. ! + \*--------------------------------------------------------*/ + xi_h = SIG2XI[xi_h]; + xi_v = SIG2XI[xi_v]; + + buff = mq_bit_decode(coder->bitcoder, XI2CONT[(xi_h << 2) | xi_v][0]); + + /*--------------------------------------------------------*\ + ! Set the sign and sig. state for the current sample. ! + \*--------------------------------------------------------*/ + stripe[k].xi |= ((XI2CONT[(xi_h << 2) | xi_v][1] ^ buff) << l); + stripe[k].sigma |= bit_mask; + } + } + } + /*--------------------------------------------------------*\ + ! Set the significant bit in the coder stripe structure. ! + \*--------------------------------------------------------*/ + 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 ! -! ---- ------ --------- ------- --------------------- ! -! - 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function can be used to transform a convex hull slope value from a 64 bit ! +! floating point format to a log2 format that can be saved to a 16 bit integer ! +! to make the slope values smaller and more managable. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! lambda bwc_field* - Floating point representation ! +! of a convex hull slope value. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! uint64 - Integer representation of a ! +! convex hull slope value in ! +! log2 format. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 07.03.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static uint16 -slope2log(const double lambda) +slope2log(double const lambda) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 exponent, mantissa, raw; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 exponent, mantissa; + uint64 raw; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(lambda > 0); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(lambda > 0); - raw = *(uint64*)λ + /*--------------------------------------------------------*\ + ! Dereference the floating point value as an integer and ! + ! extract its exponent and mantissa values. ! + \*--------------------------------------------------------*/ + raw = *(uint64*)λ - exponent = (uint64)((raw & 0x7FF0000000000000) >> 44) - 0x41F00; - mantissa = (uint64)((raw & 0x000FFFFFFFFFFFFF) >> 44); - raw = (exponent + frac2log[mantissa]) + 0x10000; + exponent = (uint64)((raw & 0x7FF0000000000000) >> 44) - 0x41F00; + mantissa = (uint64)((raw & 0x000FFFFFFFFFFFFF) >> 44); - if(raw > 0xFFFF) - { + /*--------------------------------------------------------*\ + ! Add the log2 representation of the mantissa to the expo- ! + ! nent, scale it to positive, natural values and return a ! + ! 16 bit representation to the function caller. ! + \*--------------------------------------------------------*/ + raw = (exponent + FRAC2LOG[mantissa]) + 0x10000; + + if(raw > 0xFFFF) + { return 0xFFFF; - } - else if(raw < 2.0) - { + } + else if(raw < 2.0) + { return 2; - } - else - { + } + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function can be used to compute the convex hull slopes for the optimal ! +! truncation points from the lengths and error estimations(mse) for each coding ! +! pass. This function should be called after a codeblock has been encoded. For ! +! more information refer to JPEG2000 by David S. Taubman and Michael W. ! +! Marcellin (p.340). ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! encoded_block bwc_encoded_block* - Defines and stores all neces- ! +! sary data for a compressed ! +! codeblock. ! +! ! +! mse double* - Array containing the distor- ! +! tion contributions of all co- ! +! ding passes. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 07.03.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -compute_convex_hull(bwc_encoded_cblk *const encoded_codeblock, double *const mse) +compute_convex_hull(bwc_encoded_blk *const encoded_block, + double const *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 INT VARIABLES: ! + \*-----------------------*/ + uint64 delta_L; - /*-----------------------*\ - ! DEFINE FLOAT VARIABLES: ! - \*-----------------------*/ - double delta_D; - double lambda[MAXIMUM_NO_PASSES + 1] = {0}; + uint64 *Length; + uint16 *Slope; + uint8 *h; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(encoded_codeblock); + uint8 hull[MAXIMUM_NO_PASSES] = {0}; - Length = encoded_codeblock->L; - Slope = encoded_codeblock->S; + uint8 hlast, i, j; - h = hull; - hlast = 0; - lambda [0] = 0xFFFFFFFFFFFFFFFF; + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + double delta_D; + double lambda[MAXIMUM_NO_PASSES + 1] = {0}; - for(i = 0; i < encoded_codeblock->Z; ++i) - { - delta_D = 0; - for(j = hlast; j <= i; ++j) - { - delta_D += mse[j]; - } + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(encoded_block); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + Length = encoded_block->L; + Slope = encoded_block->S; + + /*--------------------------------------------------------*\ + ! Initialized the first slope value with infinity, the ! + ! pointer used to walk through the hull array and the last ! + ! hull index for which a truncation point was found. ! + \*--------------------------------------------------------*/ + lambda [0] = 0xFFFFFFFFFFFFFFFF; + h = hull; + hlast = 0; + + /*--------------------------------------------------------*\ + ! Loop through all coding passes and find the optimal trun-! + ! cation points. ! + \*--------------------------------------------------------*/ + for(i = 0; i < encoded_block->Z; ++i) + { + /*--------------------------------------------------------*\ + ! Evaluate the accumulated distortion incurred, as well as ! + ! the number of bytes dropped, from truncating all coding ! + ! passes up to the last truncation point. ! + \*--------------------------------------------------------*/ + for(j = hlast, delta_D = 0; j <= i; ++j) + { + delta_D += mse[j]; + } delta_L = (hlast > 0) ? (Length[i] - Length[hlast - 1]) : Length[i]; + /*--------------------------------------------------------*\ + ! If the estimated distortion rate is negative, set the ! + ! slope value to -1 to signal a nonoptimal truncation ! + ! point. Otherwise, proceed with the slope calculation. ! + \*--------------------------------------------------------*/ 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; - } - } + { + lambda[i + 1] = 0; + } else - { - lambda[i + 1] = 0; - } - } + { + /*--------------------------------------------------------*\ + ! Decrement the index of the last trunc. point and recal- ! + ! culate the distortion rate and trunc. length until the ! + ! distortion rate lies on or above the convex hull. ! + \*--------------------------------------------------------*/ + while(delta_D >= (lambda[hlast] * delta_L)) + { + lambda[hlast] = 0; + h--; + hlast = h[0]; + for(j = hlast, delta_D = 0; j <= i; ++j) + { + delta_D += mse[j]; + } + delta_L = (hlast > 0) ? (Length[i] - Length[hlast - 1]) : Length[i]; + } - 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]); - } - } + /*--------------------------------------------------------*\ + ! Update the index of the last, optimal truncation point ! + ! and calculate its slope value. ! + \*--------------------------------------------------------*/ + 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; + } + } + } + /*--------------------------------------------------------*\ + ! Loop through and transform all slope values to log2. Set ! + ! negative slope values and the value for the last coding ! + ! pass to 1 to properly setup the convex hull. ! + \*--------------------------------------------------------*/ + for(i = 0; i <= encoded_block->Z; ++i) + { + if(lambda[i] > 0) + { + Slope[i] = slope2log(lambda[i]); + } + else if(lambda[i] < 0) + { + Slope[i] = 1; + } + else if(encoded_block->Z == i) + { + Slope[i] = 1; + } + } } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function walks through and applies the significance propagation, magni- ! +! tude refinement and cleanup pass to the bitplanes of a codeblock. The compres- ! +! sed bitstream is assembled using an arithmetic encoder. The distortion esti- ! +! mation for each codeblock is evaluated and the bwc_encoded_block structure is ! +! setup to allow for propper rate allocation and codestream assembly. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! access bwc_cblk_access* - Access to a parameter code- ! +! block and subband structure. ! +! ! +! codeblock bwc_coder_stripe* - Defines the sign, magnitude ! +! bitplane and state of a stripe. ! +! ! +! width, height, ... unsigned int(64 bit) - Spatial and temporal dimension ! +! of a codeblock. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ 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) +encode_codeblock(bwc_field *const field, + bwc_cblk_access *const access, + bwc_coder_stripe *const codeblock, + uint64 const width, + uint64 const height, + uint64 const depth, + uint16 const dt) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int64 delta_mse; - int16 k; - uint8 i, j; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + int64 delta_mse; + int16 k; + uint8 i, j; - /*-----------------------*\ - ! DEFINE FLOAT VARIABLES: ! - \*-----------------------*/ - double mse[MAXIMUM_NO_PASSES] = {0}; - double mse_scale; + /*-----------------------*\ + ! DEFINE REAL 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 CHAR VARIABLES: ! + \*-----------------------*/ + uchar *tmp; - /*-----------------------*\ - ! 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 STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; - /*-----------------------*\ - ! DEFINE FUNCTION PTR: ! - \*-----------------------*/ - uint64 (*coding_pass[3])(bwc_coder*, int8) = {significance_propagation_enc_pass, - magnitude_refinement_enc_pass, - cleanup_enc_pass}; + bwc_subb_ctrl *subb_ctrl; + bwc_subb_inf *subb_inf; - /*--------------------------------------------------------*\ - ! 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; + bwc_cblk_ctrl *cblk_ctrl; - subb_ctrl = &access->subband->control; - subb_inf = &access->subband->info; + bwc_encoded_blk *encoded_blk; + bwc_coder coder; - cblk_ctrl = &access->codeblock->control; + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(access); + assert(codeblock); + assert(access->subband->control.highband <= 15); + assert(access->subband->control.Kmax >= + access->codeblock->control.K); - encoded_cblk = access->codeblock->encoded_block; + /*-----------------------*\ + ! DEFINE FUNCTION PTR: ! + \*-----------------------*/ + uint64 (*coding_pass[3])(bwc_coder*, int8) = {significance_propagation_enc_pass, + magnitude_refinement_enc_pass, + cleanup_enc_pass}; - /*--------------------------------------------------------*\ - ! 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; + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + subb_ctrl = &access->subband->control; + cblk_ctrl = &access->codeblock->control; + + subb_inf = &access->subband->info; + + encoded_blk = &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_blk->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; + /*--------------------------------------------------------*\ + ! Evaluate the buffer increment, initial buffer size as ! + ! well as the number of full stripes and slices for the ! + ! current codeblock. ! + \*--------------------------------------------------------*/ + 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; - coder.no_full_stripe = height >> 2; - coder.no_slice = depth * dt; + /*--------------------------------------------------------*\ + ! Save the height, width and error resilience flag in the ! + ! coder structer. ! + \*--------------------------------------------------------*/ + coder.height = height; + coder.width = width; - /*--------------------------------------------------------*\ - ! 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; + coder.resilience = control->resilience; - /*--------------------------------------------------------*\ - ! 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) - { + /*--------------------------------------------------------*\ + ! Associate the significance-to-context pointer with the ! + ! appropriate lookup table for the current subband. ! + \*--------------------------------------------------------*/ + switch(subb_ctrl->highband) + { case 0: case 2: case 4: @@ -2448,287 +3293,314 @@ encode_codeblock(bwc_field *const field, bwc_cblk_access *const access, case 10: case 12: case 14: - { - coder.sig2context = SIG2CONTEXT_L; - break; - } + { + coder.sig2context = SIG2CONTEXT_L; + break; + } case 1: case 5: case 9: case 13: - { - coder.sig2context = SIG2CONTEXT_H; - break; - } + { + coder.sig2context = SIG2CONTEXT_H; + break; + } case 3: case 7: case 11: case 15: - { - coder.sig2context = SIG2CONTEXT_HH; - break; - } - } + { + coder.sig2context = SIG2CONTEXT_HH; + break; + } + default: + { + fprintf(stderr,"o##########################################################o\n"\ + "| ERROR: Invalid Highband |\n"\ + "o##########################################################o\n"); + return; + } + } - /*--------------------------------------------------------*\ - ! 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) - { + /*--------------------------------------------------------*\ + ! 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 == NULL) + { // 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)) - { + /*--------------------------------------------------------*\ + ! Initialize the entropy encoder for the current compres- ! + ! si pression run. ! + \*--------------------------------------------------------*/ + if(initialize_mq_encoder(&coder, CONTEXT_TOTAL) == EXIT_FAILURE) + { 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); + /*--------------------------------------------------------*\ + ! Calculate the subband specific weighting factor for the ! + ! distrotion calculation according to JPEG2000 (p. 378). ! + \*--------------------------------------------------------*/ + mse_scale = subb_inf->dwt_gain; + mse_scale *= (subb_ctrl->qt_step_size * subb_ctrl->qt_step_size); + mse_scale *= pow(2, cblk_ctrl->K * 2); + mse_scale /= 0x10000; - /*--------------------------------------------------------*\ - ! 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) - { + /*--------------------------------------------------------*\ + ! Loop over and apply the 3 coding passes to all available ! + ! bitplanes. ! + \*--------------------------------------------------------*/ + for(i = 2, j = 0, k = cblk_ctrl->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; - } + { + /*--------------------------------------------------------*\ + ! Reset the bit encoder for the next coding pass. ! + \*--------------------------------------------------------*/ + if(mq_next_run(coder.bitcoder) == EXIT_FAILURE) + { + free_mq_encoder(&coder); + return; + } + /*--------------------------------------------------------*\ + ! Apply the current coding pass to the bitplane and update ! + ! the distortion array accordingly. ! + \*--------------------------------------------------------*/ + 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. ! + ! 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) + 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; - } + if(coder.buff_size <= (mq_get_no_bytes(coder.bitcoder) + coder.buff_incr)) + { + coder.buff_size += ((uint64)k >> 1) * coder.buff_incr; + tmp = realloc(coder.compressed, coder.buff_size * sizeof(uchar)); + if(tmp == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free_mq_encoder(&coder); + return; + } + else + { + coder.compressed = tmp; + } - bit_coder_reset_ptr(coder.bitcoder, coder.compressed); - } + mq_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); - } + if(coder.resilience == 1) + { + 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; - } + } + /*--------------------------------------------------------*\ + ! Evalute the number of bytes generated by the bit encoder ! + ! and increase the buffer size if necessary. ! + \*--------------------------------------------------------*/ + if(coder.buff_size <= (mq_get_no_bytes(coder.bitcoder) + 16)) + { + coder.buff_size += 16; + tmp = realloc(coder.compressed, coder.buff_size * sizeof(uchar)); + if(tmp == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free_mq_encoder(&coder); + return; + } + else + { + coder.compressed = tmp; + } - 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); + mq_reset_ptr(coder.bitcoder, coder.compressed); + } + /*--------------------------------------------------------*\ + ! Flush the remaining bits in the byte buffer to the coder ! + ! output and calculate the minimum truncation lengths. ! + \*--------------------------------------------------------*/ + mq_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; + /*--------------------------------------------------------*\ + ! Save the number of significant bitplanes, insignificant ! + ! leading bitplanes and coding passes in the encoded block ! + ! structure. ! + \*--------------------------------------------------------*/ + encoded_blk->K = cblk_ctrl->K; + encoded_blk->Kmsbs = subb_ctrl->Kmax - cblk_ctrl->K; + encoded_blk->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)); + /*--------------------------------------------------------*\ + ! Resize the coder output buffer to its optimal size and ! + ! save the memory handle in the encoded codeblock struc- ! + ! ture. ! + \*--------------------------------------------------------*/ + encoded_blk->data = realloc(coder.compressed, coder.bitcoder->state->L * sizeof(uchar)); + if(encoded_blk->data == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(coder.compressed); + return; + } + else + { + coder.compressed = NULL; + } - /*--------------------------------------------------------*\ - ! Save the lengths of the coding passes in the encoded ! - ! codeblock structure. ! - \*--------------------------------------------------------*/ - bit_coder_get_pass_lengths(coder.bitcoder, encoded_cblk); + /*--------------------------------------------------------*\ + ! Save the lengths of the coding passes in the encoded ! + ! block structure. ! + \*--------------------------------------------------------*/ + mq_get_pass_lengths(coder.bitcoder, encoded_blk); - /*--------------------------------------------------------*\ - ! Free the entropy encoder structure. ! - \*--------------------------------------------------------*/ - free_bit_encoder(&coder); + /*--------------------------------------------------------*\ + ! Free the entropy encoder structure. ! + \*--------------------------------------------------------*/ + free_mq_encoder(&coder); - /*--------------------------------------------------------*\ - ! Calculate the slope values of the distortion/rate convex ! - ! hull. ! - \*--------------------------------------------------------*/ - compute_convex_hull(encoded_cblk, mse); + /*--------------------------------------------------------*\ + ! Calculate the slope values of the distortion/rate convex ! + ! hull. ! + \*--------------------------------------------------------*/ + compute_convex_hull(encoded_blk, 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function walks through and applies the significance propagation, magni- ! +! tude refinement and cleanup pass to the bitplanes of a codeblock. The wavelet ! +! coefficient are extracted from the compresssed bitstream using an arithmetic ! +! encoder. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! access bwc_cblk_access* - Access to a parameter code- ! +! block and subband structure. ! +! ! +! codeblock bwc_coder_stripe* - Defines the sign, magnitude ! +! bitplane and state of a stripe. ! +! ! +! width, height, ... unsigned int(64 bit) - Spatial and temporal dimension ! +! of a codeblock. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ 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) +decode_codeblock(bwc_field *const field, + bwc_cblk_access *const access, + bwc_coder_stripe *const codeblock, + uint64 const width, + uint64 const height, + uint64 const depth, + uint16 const dt) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - int16 k; - uint8 i, j; + /*-----------------------*\ + ! 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 STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_subb_ctrl *subb_ctrl; + bwc_encoded_blk *encoded_blk; + 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 ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(access); + assert(codeblock); + assert(access->subband->control.highband <= 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}; + /*-----------------------*\ + ! 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; + /*--------------------------------------------------------*\ + ! Save the global and subband control and encoded block ! + ! structure to temporary variables to make the code more ! + ! readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + subb_ctrl = &access->subband->control; - subb_ctrl = &access->subband->control; + encoded_blk = &access->codeblock->encoded_block; - encoded_cblk = access->codeblock->encoded_block; + /*--------------------------------------------------------*\ + ! Evaluate the number of full stripes and slices for the ! + ! current codeblock. ! + \*--------------------------------------------------------*/ + coder.no_full_stripe = height >> 2; + coder.no_slice = depth * dt; - /*--------------------------------------------------------*\ - ! 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; + /*--------------------------------------------------------*\ + ! Save the codeblock, its height and width, the error re- ! + ! silience flag and the encoded block in the coder ! + ! structure. ! + \*--------------------------------------------------------*/ + coder.data = codeblock; + coder.compressed = encoded_blk->data; - coder.no_full_stripe = height >> 2; - coder.no_slice = depth * dt; + coder.resilience = control->resilience; - /*--------------------------------------------------------*\ - ! 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; + coder.height = height; + coder.width = width; - /*--------------------------------------------------------*\ - ! 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) - { + /*--------------------------------------------------------*\ + ! Associate the significance-to-context pointer with the ! + ! appropriate lookup table for the current subband. ! + \*--------------------------------------------------------*/ + switch(subb_ctrl->highband) + { case 0: case 2: case 4: @@ -2737,645 +3609,685 @@ decode_codeblock(bwc_field *const field, bwc_cblk_access *const access, case 10: case 12: case 14: - { - coder.sig2context = SIG2CONTEXT_L; - break; - } + { + coder.sig2context = SIG2CONTEXT_L; + break; + } case 1: case 5: case 9: case 13: - { - coder.sig2context = SIG2CONTEXT_H; - break; - } + { + coder.sig2context = SIG2CONTEXT_H; + break; + } case 3: case 7: case 11: case 15: - { - coder.sig2context = SIG2CONTEXT_HH; - break; - } - } + { + coder.sig2context = SIG2CONTEXT_HH; + break; + } + default: + { + fprintf(stderr,"o##########################################################o\n"\ + "| ERROR: Invalid Highband |\n"\ + "o##########################################################o\n"); + return; + } + } - /*--------------------------------------------------------*\ - ! 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])) - { + /*--------------------------------------------------------*\ + ! Initialize the entropy encoder used for the current com- ! + ! pression run. ! + \*--------------------------------------------------------*/ + if(initialize_mq_decoder(&coder, + CONTEXT_TOTAL, + encoded_blk->L[encoded_blk->Z - 1]) == EXIT_FAILURE) + { return; - } + } - for(i = 2, j = encoded_cblk->Z, k = coder.K; k --> 0; i = 0) - { + /*--------------------------------------------------------*\ + ! Loop over and apply the 3 coding passes to all available ! + ! bitplanes. ! + \*--------------------------------------------------------*/ + for(i = 2, j = encoded_blk->Z, k = encoded_blk->K; k --> 0; i = 0) + { for(; i < 3; ++i, --j) - { - if(j == 0) - { - goto break_out; - } - decoding_pass[i](&coder, k); - } + { + /*--------------------------------------------------------*\ + ! Decode the current bitplane using the appropriate coding ! + ! pass if the information is available in the bitstream. ! + \*--------------------------------------------------------*/ + if(j != 0) + { + decoding_pass[i](&coder, k); + } + } + /*--------------------------------------------------------*\ + ! If the error resilience flag is set, decode and check if ! + ! the next 4 symbols represent a segmark. If false, set ! + ! the available coding passes to zero to abort decoding. ! + \*--------------------------------------------------------*/ + if((coder.resilience) && (((mq_bit_decode(coder.bitcoder, CONTEXT_UNI) << 3) | + (mq_bit_decode(coder.bitcoder, CONTEXT_UNI) << 2) | + (mq_bit_decode(coder.bitcoder, CONTEXT_UNI) << 1) | + mq_bit_decode(coder.bitcoder, CONTEXT_UNI)) != 0x0A)) + { + j = 0; + } + } - 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; - } - } + /*--------------------------------------------------------*\ + ! 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; - 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); + /*--------------------------------------------------------*\ + ! Free the entropy encoder structure. ! + \*--------------------------------------------------------*/ + free_mq_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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/**********************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function walks through and encodes all codeblocks of a tile parameter and ! +! sets up the corresponding convex rate-distortion hull. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! tile bwc_tile* - Structure defining a bwc tile. ! +! ! +! parameter bwc_parameter* - Parameter control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ uchar -t1_encode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const parameter) +t1_encode(bwc_field *const field, + uint16 const parID) { - /*-----------------------*\ - ! 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 INT VARIABLES: ! + \*-----------------------*/ + uint64 c; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_gl_ctrl *control; - bwc_codeblock *codeblock; - bwc_cblk_inf *cblk_info; - bwc_coder_stripe *working_buffer; - bwc_coder_stripe **memory; + uint64 cbSizeX, cbSizeY; + uint64 cbSizeZ, cbSizeTS; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(field); - assert(tile); - assert(parameter); + uint64 width, height, depth; - /*--------------------------------------------------------*\ - ! Save the global control structure to a temporary varia- ! - ! ble to make the code more readable. ! - \*--------------------------------------------------------*/ - control = &field->control; + int64 buff_size; - /*--------------------------------------------------------*\ - ! 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; + int64 j; - /*--------------------------------------------------------*\ - ! 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; + uint16 slope_max, slope_min; - /*--------------------------------------------------------*\ - ! Evaluate the number of threads used for the current com- ! - ! pression run. ! - \*--------------------------------------------------------*/ - #if defined (_OPENMP) - nThreads = control->nThreads; - #else - nThreads = 1; - #endif + int16 i, z; - /*--------------------------------------------------------*\ - ! 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; + uint8 error_flag; - /*--------------------------------------------------------*\ - ! 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) - { + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + bwc_tile *tile; + bwc_parameter *parameter; + + bwc_codeblock *codeblock; + bwc_cblk_inf *cblk_info; + + bwc_coder_stripe *working_buffer; + bwc_coder_stripe **memory; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + tile = &field->setup.tile; + parameter = &tile->parameter[parID]; + + slope_max = tile->control.slope_max; + slope_min = tile->control.slope_min; + + /*--------------------------------------------------------*\ + ! Initialize the coder stripe pointer and error flag for ! + ! correct error handling. ! + \*--------------------------------------------------------*/ + error_flag = EXIT_SUCCESS; + memory = NULL; + + /*--------------------------------------------------------*\ + ! Evaluate the width, height and depth of the current para-! + ! meter and calculate the size of the buffer used to store ! + ! the codeblock as stripes of 4 vert. adjacent samples. ! + \*--------------------------------------------------------*/ + width = parameter->info.X1 - parameter->info.X0; + height = parameter->info.Y1 - parameter->info.Y0; + depth = parameter->info.Z1 - parameter->info.Z0; + + buff_size = ((uint64)(1 << control->cbX) * (1 << (control->cbY - 2)) * + (1 << control->cbZ) * (1 << control->cbTS)) + 2; + + /*--------------------------------------------------------*\ + ! Allocate and initialize an array of working buffers that ! + ! are used by the OpenMP threads to encode the codeblock. ! + ! For a serial run only one working buffer is allocated. ! + \*--------------------------------------------------------*/ + memory = calloc(control->numThreads, sizeof(bwc_coder_stripe*)); + if(memory == NULL) + { // memory allocation error fprintf(stderr, MEMERROR); - return 1; - } + error_flag = EXIT_FAILURE; + goto T1_ENCODE_OUT; + } - /*--------------------------------------------------------*\ - ! 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; - } + for(i = 0; i < control->numThreads; ++i) + { + memory[i] = calloc(buff_size, sizeof(bwc_coder_stripe)); + if(memory[i] == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + error_flag = EXIT_FAILURE; + goto T1_ENCODE_OUT; + } /*--------------------------------------------------------*\ - ! 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. ! + ! The first two stripes are initialized as dummies to rep- ! + ! resent the boundaries of the codeblock and uncouple it ! + ! from its neighbours. ! \*--------------------------------------------------------*/ 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. ! + ! Initialize the sample and bit arrays used to store the ! + ! sample magnitudes and bitplanes of a single stripe. ! \*--------------------------------------------------------*/ 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) + { + memory[i][j].sample = calloc(4, sizeof(uint64)); + memory[i][j].bit = calloc(PREC_BIT, sizeof(uint8)); + if(memory[i][j].sample == NULL || + memory[i][j].bit == NULL) { - for(; j >= 0; --j) - { - free(memory[i][j].bit); - free(memory[i][j].sample); - } - j = buff_size; - free(memory[i]); + // memory allocation error + fprintf(stderr, MEMERROR); + error_flag = EXIT_FAILURE; + goto T1_ENCODE_OUT; } - 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 - { + #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. ! + ! Associate the working buffers with their respective data ! + ! blocks and loop over and encode all codeblocks. ! \*--------------------------------------------------------*/ #if defined (_OPENMP) - working_buffer = &memory[omp_get_thread_num()][2]; + working_buffer = &memory[omp_get_thread_num()][2]; #else - working_buffer = &memory[0][2]; + working_buffer = &memory[0][2]; #endif - /*--------------------------------------------------------*\ - ! Loop through and encode all codeblocks for the current ! - ! parameter. ! - \*--------------------------------------------------------*/ #if defined(_OPENMP) - #pragma omp for + #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; + for(c = 0; c < parameter->control.numCodeblocks; ++c) + { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! 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; + /*--------------------------------------------------------*\ + ! 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); + /*--------------------------------------------------------*\ + ! Copy the wavelet coefficients to the working buffer and ! + ! encode the encoded block information. ! + \*--------------------------------------------------------*/ + 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); + 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) + /*--------------------------------------------------------*\ + ! Reset the working buffer for the next encoding pass. ! + \*--------------------------------------------------------*/ + cblkreset_fwd(working_buffer, + cbSizeX, + cbSizeY, + cbSizeZ, + cbSizeTS); + + /*--------------------------------------------------------*\ + ! Update the codestream memory usage. ! + \*--------------------------------------------------------*/ + field->memory.usage.codestream += codeblock->encoded_block.L[codeblock->encoded_block.Z - 1]; + + /*--------------------------------------------------------*\ + ! If a compressed bitstream has been created, walk through ! + ! all coding passes and update the minimum and maximum ! + ! slope values for the current tile parameter. ! + \*--------------------------------------------------------*/ + if(codeblock->encoded_block.data) { - /*--------------------------------------------------------*\ - ! ...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]); - } + for(z = 0; z <= codeblock->encoded_block.Z; ++z) + { + if(codeblock->encoded_block.S[z]) + { + 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/maximum slope values for the current ! + ! parameter tile, deallocate the working buffer array and ! + ! memory blocks and return to the function caller. ! + \*--------------------------------------------------------*/ + tile->control.slope_max = slope_max; + tile->control.slope_min = slope_min; - /*--------------------------------------------------------*\ - ! 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; + /*--------------------------------------------------------*\ + ! Update the minimum/maximum slope values for the current ! + ! parameter tile, deallocate the working buffer array and ! + ! memory blocks and return to the function caller. ! + \*--------------------------------------------------------*/ + if(field->data.body[field->data.idx].memory != NULL) + { + field->memory.usage.data -= field->data.body[field->data.idx].size; + free(field->data.body[field->data.idx].memory); + memset(&field->data.body[field->data.idx], 0, sizeof(bwc_packed_stream)); + } + field->data.idx++; + +T1_ENCODE_OUT: - /*--------------------------------------------------------*\ - ! Deallocate the working buffer pointer array and memory ! - ! blocks. ! - \*--------------------------------------------------------*/ - for(i = 0; i < nThreads; ++i) - { - for(j = 0; j < buff_size; ++j) + if(memory != NULL) + { + for(i = 0; i < control->numThreads; ++i) { - free(memory[i][j].bit); - free(memory[i][j].sample); + if(memory[i] != NULL) + { + for(j = 0; j < buff_size; ++j) + { + free(memory[i][j].sample); + free(memory[i][j].bit); + } + } + free(memory[i]); } - free(memory[i]); - } - free(memory); + } + free(memory); - return 0; + return error_flag; } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function walks through and decodes all codeblocks of a tile parameter. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! tile bwc_tile* - Structure defining a bwc tile. ! +! ! +! parameter bwc_parameter* - Parameter control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 02.07.2018 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 17.04.2020 Patrick Vogler B87E7E4 V 0.1.0 function updated ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ uchar -t1_decode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const parameter) +t1_decode(bwc_field *const field, + uint16 const parID) { - /*-----------------------*\ - ! 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 INT VARIABLES: ! + \*-----------------------*/ + uint64 c; - /*-----------------------*\ - ! 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; + uint64 cbSizeX, cbSizeY; + uint64 cbSizeZ, cbSizeTS; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(field); - assert(tile); - assert(parameter); + uint64 memory_usage; - /*--------------------------------------------------------*\ - ! Save the global control structure to a temporary varia- ! - ! ble to make the code more readable. ! - \*--------------------------------------------------------*/ - control = &field->control; + uint64 width, height; + uint64 depth, dt; - /*--------------------------------------------------------*\ - ! 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; + int64 buff_size, param_size; - /*--------------------------------------------------------*\ - ! Evaluate the number of threads used for the current de- ! - ! compression run. ! - \*--------------------------------------------------------*/ - #if defined (_OPENMP) - nThreads = control->nThreads; - #else - nThreads = 1; - #endif + int64 j; - /*--------------------------------------------------------*\ - ! 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; + int16 i; - /*--------------------------------------------------------*\ - ! 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) - { + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + + bwc_tile *tile; + bwc_parameter *parameter; + + 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); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + + tile = &field->setup.tile; + parameter = &tile->parameter[parID]; + + /*--------------------------------------------------------*\ + ! Evaluate the width, height and depth of the current para-! + ! meter and calculate the size of the buffer used to store ! + ! the codeblock as stripes of 4 vert. adjacent samples. ! + \*--------------------------------------------------------*/ + width = parameter->info.X1 - parameter->info.X0; + height = parameter->info.Y1 - parameter->info.Y0; + depth = parameter->info.Z1 - parameter->info.Z0; + dt = parameter->info.TS1 - parameter->info.TS0; + + buff_size = ((uint64)(1 << control->cbX) * (1 << (control->cbY - 2)) * + (1 << control->cbZ) * (1 << control->cbTS)) + 2; + + /*--------------------------------------------------------*\ + ! If the numerical data is streamed to the file allocate a ! + ! working buffer for the current tile parameter samples. ! + \*--------------------------------------------------------*/ + if((field->data.flag & DATA_STR) == 0) + { + param_size = (int64)width * height * depth * dt; + + field->setup.working_buffer.access = + field->setup.working_buffer.memory = calloc(param_size, sizeof(bwc_float)); + if(field->setup.working_buffer.memory == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + field->memory.usage.setup += (param_size * sizeof(bwc_float)); + } + + /*--------------------------------------------------------*\ + ! Associate the working buffer with the data pointer in ! + ! the bwc_parameter structure. ! + \*--------------------------------------------------------*/ + parameter->data = (bwc_float*)field->setup.working_buffer.memory; + + /*--------------------------------------------------------*\ + ! Verify, that the memory limit is not exceeded by the ! + ! following memory allocations. ! + \*--------------------------------------------------------*/ + memory_usage = control->numThreads * (sizeof(bwc_coder_stripe*) + + buff_size * (sizeof(bwc_coder_stripe) + + sizeof(uint8) * PREC_BIT + + sizeof(uint64) * 4)); + + memory_usage += field->memory.usage.codestream + + field->memory.usage.data + + field->memory.usage.setup + + field->memory.usage.stat; + + if(memory_usage > field->memory.limit) + { // memory allocation error fprintf(stderr, MEMERROR); - return 1; - } + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! 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;) + /*--------------------------------------------------------*\ + ! Allocate and initialize an array of working buffers that ! + ! are used by the OpenMP threads to encode the codeblock. ! + ! For a serial run only one working buffer is allocated. ! + \*--------------------------------------------------------*/ + memory = calloc(control->numThreads, sizeof(bwc_coder_stripe*)); + if(memory == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } + + for(i = 0; i < control->numThreads; ++i) + { + memory[i] = calloc(buff_size, sizeof(bwc_coder_stripe)); + if(memory[i] == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + for(; i --> 0;) { - free(memory[i][j].bit); - free(memory[i][j].sample); + for(j = buff_size - 1; j --> 0;) + { + free(memory[i][j].sample); + free(memory[i][j].bit); + } + free(memory[i]); } - free(memory[i]); - } - free(memory); - return 1; - } + free(memory); + return EXIT_FAILURE; + } /*--------------------------------------------------------*\ - ! 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. ! + ! The first two stripes are initialized as dummies to rep- ! + ! resent the boundaries of the codeblock and uncouple it ! + ! from its neighbours. ! \*--------------------------------------------------------*/ 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. ! + ! Initialize the sample and bit arrays used to store the ! + ! sample magnitudes and bitplanes of of a specific stripe. ! \*--------------------------------------------------------*/ 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) + { + memory[i][j].sample = calloc(4, sizeof(uint64)); + memory[i][j].bit = calloc(PREC_BIT, sizeof(uint8)); + if(memory[i][j].sample == NULL || + memory[i][j].bit == NULL) { - for(; j >= 0; --j) - { - free(memory[i][j].bit); - free(memory[i][j].sample); - } - j = buff_size; - free(memory[i]); + // memory allocation error + fprintf(stderr, MEMERROR); + for(; i >= 0; --i) + { + for(; j >= 0; --j) + { + free(memory[i][j].sample); + free(memory[i][j].bit); + } + j = buff_size; + free(memory[i]); + } + free(memory); + return EXIT_FAILURE; } - free(memory); - return 1; - } - } - } + } + } - #if defined(_OPENMP) - #pragma omp parallel private(working_buffer, codeblock, cblk_info, subb_ctrl,\ - cbSizeX, cbSizeY, cbSizeZ, cbSizeTS) - #endif - { + #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. ! + ! Associate the working buffers with their respective data ! + ! blocks and loop over and encode all codeblocks. ! \*--------------------------------------------------------*/ #if defined (_OPENMP) - working_buffer = &memory[omp_get_thread_num()][2]; + working_buffer = &memory[omp_get_thread_num()][2]; #else - working_buffer = &memory[0][2]; + working_buffer = &memory[0][2]; #endif - /*--------------------------------------------------------*\ - ! Loop through and encode all codeblocks for the current ! - ! parameter. ! - \*--------------------------------------------------------*/ #if defined(_OPENMP) - #pragma omp for + #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; + for(c = 0; c < parameter->control.numCodeblocks; ++c) + { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures 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 width, height, depth and dt as well as the ! + ! index of the first significant bitplane 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; + 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); + /*--------------------------------------------------------*\ + ! Check if the current codeblock has at least one coding ! + ! pass. If true, reset the working buffer, decode the code-! + ! block information and copy it to the data memory block. ! + \*--------------------------------------------------------*/ + if(codeblock->encoded_block.Z > 0) + { + 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); - } + 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); - } - } + 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) - { + /*--------------------------------------------------------*\ + ! Deallocate the working buffer pointer array and memory ! + ! blocks and return to the function caller. ! + \*--------------------------------------------------------*/ + for(i = 0; i < control->numThreads; ++i) + { for(j = 0; j < buff_size; ++j) - { - free(memory[i][j].bit); - free(memory[i][j].sample); - } + { + free(memory[i][j].sample); + free(memory[i][j].bit); + } free(memory[i]); - } - free(memory); + } + free(memory); - return 0; + return EXIT_SUCCESS; } diff --git a/src/library/tier2.c b/src/library/tier2.c index 048dad1..718a7db 100755 --- a/src/library/tier2.c +++ b/src/library/tier2.c @@ -1,82 +1,53 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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. || -|| || -\*==================================================================================================================================*/ - -/************************************************************************************************************\ -|| _ _ _ ____ _ _ _ ___ ____ || -|| | |\ | | | | | | \ |___ || -|| | | \| |___ |___ |__| |__/ |___ || -|| || -\************************************************************************************************************/ +/*====================================================================================================================*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +|| DESCRIPTION: || +|| ------------ || +|| This file describes a set of functions that can be used to de-/encode bwc codeblocks || +|| described by the bwc_field structure according to the embedded block coding paradigm || +|| described by the JPEG 2000 standard. For more information please refere to JPEG2000 || +|| by D. S. Taubman and M. W. Marcellin. || +|| || +|| ---------------------------------------------------------------------------------------------------------------- || +|| || +|| 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. || +|| || +\*====================================================================================================================*/ +/**********************************************************************************************************************\ +|| _ _ _ ____ _ _ _ ___ ____ || +|| | |\ | | | | | | \ |___ || +|| | | \| |___ |___ |__| |__/ |___ || +|| || +\**********************************************************************************************************************/ #include #include #include @@ -93,247 +64,255 @@ #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); \ - } \ +/**********************************************************************************************************************\ +|| _ _ ____ ____ ____ ____ ____ || +|| |\/| |__| | |__/ | | [__ || +|| | | | | |___ | \ |__| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! DESCRIPTION: ! +! ------------ ! +! These macros define a variable length encoder and decoder for the delta z (new ! +! coding passes) information stored in a packet header. ! +! ! +! MACROS: ! +! ------- ! +! Name Description ! +! ---- ----------- ! +! encode_delta_z - Delta Z encoder. ! +! ! +! decode_delta_z - Delta Z decoder. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 13.05.2019 Patrick Vogler B87D120 V 0.1.0 Macros created. ! +! 19.04.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +#define encode_delta_z(stream, delta_z) \ +{ \ + if(delta_z == 1) \ + { \ + emit_bit(stream, 0); \ + } \ + else if(delta_z == 2) \ + { \ + emit_bit(stream, 1); \ + emit_bit(stream, 0); \ + } \ + else if(delta_z < 6) \ + { \ + delta_z -= 3; \ + emit_bit(stream, 1); \ + emit_bit(stream, 1); \ + emit_bit(stream, 0x02 & delta_z); \ + emit_bit(stream, 0x01 & delta_z); \ + } \ + else if(delta_z < 37) \ + { \ + delta_z -= 6; \ + emit_bit(stream, 1); \ + emit_bit(stream, 1); \ + emit_bit(stream, 1); \ + emit_bit(stream, 1); \ + emit_bit(stream, 0x10 & delta_z); \ + emit_bit(stream, 0x08 & delta_z); \ + emit_bit(stream, 0x04 & delta_z); \ + emit_bit(stream, 0x02 & delta_z); \ + emit_bit(stream, 0x01 & delta_z); \ + } \ + else if(delta_z < 293) \ + { \ + delta_z -= 37; \ + emit_bit(stream, 1); \ + emit_bit(stream, 1); \ + emit_bit(stream, 1); \ + emit_bit(stream, 1); \ + emit_bit(stream, 1); \ + emit_bit(stream, 1); \ + emit_bit(stream, 1); \ + emit_bit(stream, 1); \ + emit_bit(stream, 1); \ + emit_bit(stream, 0x080 & delta_z); \ + emit_bit(stream, 0x040 & delta_z); \ + emit_bit(stream, 0x020 & delta_z); \ + emit_bit(stream, 0x010 & delta_z); \ + emit_bit(stream, 0x008 & delta_z); \ + emit_bit(stream, 0x004 & delta_z); \ + emit_bit(stream, 0x002 & delta_z); \ + 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; \ - } \ - } \ - } \ +#define decode_delta_z(stream, delta_z) \ +{ \ + if(get_bit(stream) == 0) \ + { \ + delta_z = 1; \ + } \ + else if(get_bit(stream) == 0) \ + { \ + delta_z = 2; \ + } \ + else \ + { \ + delta_z = (get_bit(stream) << 1) | \ + get_bit(stream); \ + \ + if(delta_z < 3) \ + { \ + delta_z += 3; \ + } \ + else \ + { \ + delta_z = (get_bit(stream) << 4) | \ + (get_bit(stream) << 3) | \ + (get_bit(stream) << 2) | \ + (get_bit(stream) << 1) | \ + get_bit(stream); \ + \ + if(delta_z < 31) \ + { \ + delta_z += 6; \ + } \ + else \ + { \ + delta_z = (get_bit(stream) << 7) | \ + (get_bit(stream) << 6) | \ + (get_bit(stream) << 5) | \ + (get_bit(stream) << 4) | \ + (get_bit(stream) << 3) | \ + (get_bit(stream) << 2) | \ + (get_bit(stream) << 1) | \ + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/**********************************************************************************************************************\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to signal the length of a coding pass contribution for a ! +! specified quality layer. For a more information please refer to p. 521 in JPEG ! +! 2000 by David S. Taubman and Michael W. Marcellin. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! header bwc_stream* - Stream used to access packet ! +! header information. ! +! ! +! codeblock bwc_codeblock* - Structure defining a bwc code- ! +! block. ! +! ! +! quality_layer singed int(8 bit) - Quality layer index. ! +! ! +! est unsigned char - Flag indicating quality layer ! +! size estimation or final as- ! +! sembly. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! - - ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 29.04.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 25.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static void -encode_length(bwc_stream *const header, bwc_codeblock *const codeblock, - int8 const quality_layer, - uchar const estimate) +encode_length(bwc_stream *const header, + bwc_codeblock *const codeblock, + int8 const quality_layer, + uchar const est) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint32 L; - int32 L_bits; - uint16 beta, max_beta; - uint16 cp_bits; - int16 *cp_contr; - int16 z_curr, z_prev; + /*-----------------------*\ + ! 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 STRUCTS: ! + \*-----------------------*/ + bwc_cblk_ctrl *cblk_ctrl; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(codeblock); - assert(header); + /*-----------------------*\ + ! 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; + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures 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; + 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; + beta = (est == 0) ? 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); + 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; + 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; + max_beta = (max_beta < L_bits) ? L_bits : max_beta; - while(beta < max_beta) - { - bwc_emit_bit(header, 1); + while(beta < max_beta) + { + emit_bit(header, 1); beta++; - } + } - bwc_emit_bit(header, 0); + emit_bit(header, 0); - L_bits = 1 << (beta + cp_bits - 1); + L_bits = 1 << (beta + cp_bits - 1); - while(L_bits > 0) - { - bwc_emit_bit(header, L & L_bits); + while(L_bits > 0) + { + emit_bit(header, L & L_bits); L_bits >>= 1; - } + } - if(estimate == 0) - { + if(est == 0) + { cblk_ctrl->beta = beta; cblk_ctrl->beta_est = beta; - } - else if(estimate == 1) - { + } + else if(est == 1) + { cblk_ctrl->beta_est = beta; - } + } } /*----------------------------------------------------------------------------------------------------------*\ @@ -362,1343 +341,1277 @@ encode_length(bwc_stream *const header, bwc_codeblock *const codeblock, ! ! ! Date Author Change Id Release Description Of Change ! ! ---- ------ --------- ------- --------------------- ! -! 29.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! 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) +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 INT VARIABLES: ! + \*-----------------------*/ + uint32 i; + uint16 L_bits; + int16 *cp_contr; + int16 z_curr, z_prev; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_cblk_ctrl *cblk_ctrl; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_cblk_ctrl *cblk_ctrl; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(codeblock); - assert(header); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(codeblock); + assert(header); - cblk_ctrl = &codeblock->control; - cp_contr = cblk_ctrl->cp_contr; + cblk_ctrl = &codeblock->control; + cp_contr = cblk_ctrl->cp_contr; - while(bwc_get_bit(header)) - { + while(get_bit(header) != 0) + { cblk_ctrl->beta++; - } + } - z_curr = cp_contr[quality_layer ] - 1; - z_prev = cp_contr[quality_layer - 1] - 1; + 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); + L_bits = cblk_ctrl->beta + (uint16)log2(z_curr - z_prev); - for(i = 0; L_bits > 0; --L_bits) - { + for(i = 0; L_bits > 0; --L_bits) + { i <<= 1; - i |= bwc_get_bit(header); - } + i |= get_bit(header); + } - codeblock->encoded_block->L[z_curr] = ((z_prev >= 0) ? codeblock->encoded_block->L[z_prev] : 0) + i; + 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to assemble a codestream packet for a specified precinct ! +! (precinct_idx) and quality layer (q_layer). In order to facilitate fast quali- ! +! ty layer creation, the est flag can be used to instruct the function to esti- ! +! mate the packet header size and circumvent the packet body creation. ! +! For est = 0, both the packet header and body are assembled and the tile size ! +! estimation is augment with the calculated packet size. Additionally, if an er- ! +! ror resilient codestream is constructed, the size of the corresponding error ! +! markers are accounted for in the tile size evaluation. ! +! If an error is encountered the function will return a -1 in lieu of the packet ! +! header size. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! resolution bwc_resolution* - Structure defining a bwc reso- ! +! lution level. ! +! precinct_idx unsigned int(32 bit) - Index of the current precinct. ! +! ! +! quality_layer signed int(16 bit) - Index of the current quality ! +! layer. ! +! ! +! est unsigned char - Flag indicating quality layer ! +! size estimation or final as- ! +! sembly. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! integer(16 bit) - Packet header size. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 29.04.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 25.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ 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) +create_packet(bwc_field *const field, + bwc_resolution *const resolution, + uint32 const precinct_idx, + int16 const quality_layer, + uchar const est) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint32 size, start, end; - uint32 k; - uint16 cb; - int16 *cp_contr; - int16 delta_z; - int8 m; + /*-----------------------*\ + ! 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 STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_tile_inf *tile_info; + bwc_packet *packet; + bwc_precinct *precinct; + bwc_codeblock *codeblock; + bwc_stream *header; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(field); - assert(tile); - assert(resolution); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + 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]; + /*--------------------------------------------------------*\ + ! Save the global and tile control as well as the packet ! + ! structure to temporary variables to make the code more ! + ! readable. ! + \*--------------------------------------------------------*/ + control = &field->control; - /*--------------------------------------------------------*\ - ! Check if the current packet has any codeblock contribu- ! - ! tion. ! - \*--------------------------------------------------------*/ - if(packet->e) - { + tile_info = field->setup.tile.info; + + packet = &resolution->packet[quality_layer * (resolution->control.numPrecincts + precinct_idx)]; + + /*--------------------------------------------------------*\ + ! Proceed with packet creation if it is marked to contri- ! + ! bute to the current quality layer. ! + \*--------------------------------------------------------*/ + if(packet->e == 1) + { /*--------------------------------------------------------*\ - ! Initialize the stream that is used to assemble the pack- ! - ! et header. ! + ! Initialize the stream used for packet header assembly ! + ! and emit the contribution bit that signals a non-empty ! + ! packet body. ! \*--------------------------------------------------------*/ - header = bwc_init_stream(NULL, PACKET_HEADER_SIZE, 'c'); - if(!header) - { - // memory allocation error - return -1; - } + header = init_stream(NULL, PACKET_HEADER_SIZE, 'c'); + if(header == NULL) + { + // memory allocation error + return -1; + } + + emit_bit(header, 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. ! + ! For final assembly (est == 0), allocate the packet body ! + ! stream used to hold its input for the current q. layer. ! \*--------------------------------------------------------*/ - 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); + if(est == 0) + { + packet->body.access = + packet->body.memory = calloc(packet->body.size, sizeof(uchar)); + if(packet->body.memory == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return -1; + } + } /*--------------------------------------------------------*\ ! Iterate over all codeblocks in all subbands to assemble ! - ! the packet header and, if no estimation has been spec- ! - ! ified, body. ! + ! the packet header and, if specified (est = 0) 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(m = 0; m < resolution->control.numSubbands; ++m) + { + precinct = &resolution->subband[m].precinct[precinct_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) + for(cb = 0; cb < precinct->control.numCodeblocks; ++cb) { - /*--------------------------------------------------------*\ - ! 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); + /*--------------------------------------------------------*\ + ! 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; - /*--------------------------------------------------------*\ - ! 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); - } + /*--------------------------------------------------------*\ + ! Evaluate the new coding passes added to the packet body ! + ! for the current quality layer. ! + \*--------------------------------------------------------*/ + delta_z = cp_contr[quality_layer] - cp_contr[quality_layer - 1]; - /*--------------------------------------------------------*\ - ! 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 no contribution by the current codeblock has previous-! + ! ly been made, ... ! + \*--------------------------------------------------------*/ + if(cp_contr[quality_layer - 1] == 0) + { + /*--------------------------------------------------------*\ + ! ... encode the inclusion tagtree and, if a packet input ! + ! is available, the leading non-significant bitplane tag- ! + ! tree for the current codeblock. ! + \*--------------------------------------------------------*/ + encode_tagtree(&precinct->control.tag_inclusion, header, quality_layer + 1, cb, 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; + if(cp_contr[quality_layer] != 0) + { + for(k = 1; k <= codeblock->encoded_block.Kmsbs + 1u; ++k) + { + encode_tagtree(&precinct->control.tag_msbs, header, k, cb, est); + } + } + } + /*--------------------------------------------------------*\ + ! If a contribution has already been made, transmit a flag ! + ! to signal if new coding passes are available. ! + \*--------------------------------------------------------*/ + else + { + emit_bit(header, delta_z); + } + + /*--------------------------------------------------------*\ + ! If new coding passes are available, ... ! + \*--------------------------------------------------------*/ + if(delta_z != 0) + { + /*--------------------------------------------------------*\ + ! encode the new coding passes and corresponding lengths ! + ! in the packet header. ! + \*--------------------------------------------------------*/ + encode_delta_z(header, delta_z); + encode_length(header, codeblock, quality_layer, est); /*--------------------------------------------------------*\ - ! ...add up the packet body size for the final quality ! - ! layer assembly or... ! + ! For final quality layer (est = 1) or packet (est = 0) as-! + ! sembly, evaluate the start and end points as well as the ! + ! contribution size and.. ! \*--------------------------------------------------------*/ - 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; - } - } + if(est <= 1) + { + start = (cp_contr[quality_layer - 1] == 0) ? 0 : codeblock->encoded_block.L[cp_contr[quality_layer - 1] - 1]; + end = (cp_contr[quality_layer] == 0) ? 0 : codeblock->encoded_block.L[cp_contr[quality_layer] - 1]; + size = end - start; + + /*--------------------------------------------------------*\ + ! ...augment the packet body size for final quality layer ! + ! assembly or... ! + \*--------------------------------------------------------*/ + if(est == 1) + { + packet->body.size += size; + } + /*--------------------------------------------------------*\ + ! ...copy the contribution to the packet body for final ! + ! packet assembly. ! + \*--------------------------------------------------------*/ + else + { + memcpy(packet->body.access, codeblock->encoded_block.data + start, size); + packet->body.access += size; + } + } + } } - } - } + } /*--------------------------------------------------------*\ - ! Flush the remaining bits from the buffer to the header ! - ! stream. ! + ! Flush the remaining bits 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. ! + ! For packet header size estimation (est > 0), reset the ! + ! non-empty packet flag, free the header stream and return ! + ! the estimated header size to the function caller. ! \*--------------------------------------------------------*/ - if(est) - { - if(est == 2) - { - packet->e = 0; - } + if(est != 0) + { + if(est == 2) + { + packet->e = 0; + } - k = header->L; - bwc_terminate_stream(header, NULL); - return k; - } + k = header->L; + 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. ! + ! For final packet assembly, terminate the header stream, ! + ! evaluate the packet size, augment the tile body size est.! + ! and return the header size to the function caller. ! \*--------------------------------------------------------*/ else - { - if(bwc_terminate_stream(header, &packet->header)) - { - // memory allocation error - return -1; - } + { + if(terminate_stream(header, &packet->header) == EXIT_FAILURE) + { + return -1; + } - packet->size = packet->body.size + packet->header.size; + packet->size = packet->body.size + packet->header.size; - return packet->header.size; - } - } - else - { + control->packed_tile_size[tile_info->index] += packet->size; + control->packed_tile_size[tile_info->index] += (control->resilience != 0) ? 10 : 0; + + return packet->header.size; + } + } + /*--------------------------------------------------------*\ + ! If no contribution is available and ... ! + \*--------------------------------------------------------*/ + 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... ! + ! ... for packet header size estimation (est > 0), reset ! + ! the non-empty packet flag and return a header size of 1. ! \*--------------------------------------------------------*/ - if(est) - { - if(est == 2) - { - packet->e = 0; - } - - return 1; - } + if(est != 0) + { + 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. ! + ! ... for final packet assembly, set the packet and header ! + ! size to 1, augment the tile body size estimation and re- ! + ! turn the header size to the fct. caller. ! \*--------------------------------------------------------*/ else - { - packet->size = 1; - packet->header.size = 1; + { + 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; - } + control->packed_tile_size[tile_info->index] += packet->size; + control->packed_tile_size[tile_info->index] += (control->resilience != 0) ? 10 : 0; - return packet->header.size; - } - } + return 1; + } + } } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function iterates overall quality layers for every precinct in all resolu- ! +! tion levels to create the codestream packets for a tile parameters. ! +! If an error occurres during packet creation, the function returns an error flag ! +! to the function caller. ! +! If packet creation for all quality layers is successful, the function iterates ! +! over all codeblocks that are a part of the current precinct, frees all encoded ! +! memory blocks and resets the encoded block structure for the next (de-)compres- ! +! sion run. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 29.04.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 26.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static uchar -create_packets(bwc_field *const field, bwc_tile *const tile) +create_packets(bwc_field *const field) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 cb, p; - uint16 j, r; - uint8 l, m; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 cb, p; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_gl_ctrl *control; - bwc_gl_inf *info; - bwc_parameter *parameter; - bwc_resolution *resolution; - bwc_codeblock *codeblock; + uint16 j, r; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(field); - assert(tile); + uint8 l, m; - /*--------------------------------------------------------*\ - ! Save the global control and info structure to temporary ! - ! variables to make the code more readable. ! - \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *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. ! - \*--------------------------------------------------------*/ + bwc_tile *tile; + + bwc_parameter *parameter; + + bwc_resolution *resolution; + + bwc_codeblock *codeblock; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = &field->info; + + tile = &field->setup.tile; + + /*--------------------------------------------------------*\ + ! Iterate overall quality layers for every precinct in all ! + ! resolution levels and assemble the tile param. packets. ! + \*--------------------------------------------------------*/ + for(j = 0; j < info->numParams; ++j) + { 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(r = 0; r < control->numDecomp + 1; ++r) + { + resolution = ¶meter->resolution[r]; - for(p = 0; p < resolution->control.number_of_precincts; ++p) - { - for(l = 0; l < control->nLayers; ++l) + for(p = 0; p < resolution->control.numPrecincts; ++p) { - if(create_packet(field, tile, resolution, p, l, 0) < 0) - { - // memory allocation error - return 1; - } + for(l = 0; l < control->numLayers; ++l) + { + if(create_packet(field, resolution, p, l, 0) < 0) + { + // memory allocation error + return EXIT_FAILURE; + } + } + + /*--------------------------------------------------------*\ + ! If packet assembly is successful, iterate over all code- ! + ! blocks that are a part of the current precinct and reset ! + ! the encoded block structure for the next run. ! + \*--------------------------------------------------------*/ + for(m = 0; m < resolution->control.numSubbands; ++m) + { + for(cb = 0; cb < resolution->subband[m].precinct[p].control.numCodeblocks; ++cb) + { + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables 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_blk)); + memset(codeblock->control.cp_contr, 0, sizeof(int16) * control->numLayers); + } + } } - - /*--------------------------------------------------------*\ - ! 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; + } + } + return EXIT_SUCCESS; } - -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function iterates overall quality layers for every precinct in all resolu- ! +! tion levels to create the codestream packets for a tile parameters. ! +! If an error occurres during packet creation, the function returns an error flag ! +! to the function caller. ! +! If packet creation for all quality layers is successful, the function iterates ! +! over all codeblocks that are a part of the current precinct, frees all encoded ! +! memory blocks and resets the encoded block structure for the next (de-)compres- ! +! sion run. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! threshold unsigned int(16 bit) - Convex hull slope threshold ! +! value. ! +! ! +! quality_layer signed int(16 bit) - Index of the current quality ! +! layer. ! +! ! +! est unsigned char - Flag indicating quality layer ! +! size estimation or final as- ! +! sembly. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! integer(16 bit) - Quality layer size. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 29.04.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 26.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static int64 -create_quality_layer(bwc_field *const field, bwc_tile *const tile, - uint16 const threshold, - int16 const q_layer, - uchar const est) +create_quality_layer(bwc_field *const field, + uint16 const threshold, + int16 const quality_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 INT VARIABLES: ! + \*-----------------------*/ + uint64 cb, p; + uint64 nPrec; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_gl_ctrl *control; - bwc_gl_inf *info; - bwc_parameter *parameter; - bwc_resolution *resolution; - bwc_subband *subband; - bwc_codeblock *codeblock; + int64 estimated_ql_size; + int64 estimated_ph_size; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(field); - assert(tile); + uint16 j, r; - /*--------------------------------------------------------*\ - ! Save the global control and info structure to temporary ! - ! variables to make the code more readable. ! - \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; + int16 *cp_contr; + int16 z; - 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. ! - \*--------------------------------------------------------*/ + uint8 l, m; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *info; + + bwc_tile *tile; + + bwc_parameter *parameter; + + bwc_resolution *resolution; + + bwc_subband *subband; + + bwc_codeblock *codeblock; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = &field->info; + + tile = &field->setup.tile; + + /*--------------------------------------------------------*\ + ! Loop over all codeblocks in the current tile and assem- ! + ! ble the quality layer defined by the slope threshold. ! + \*--------------------------------------------------------*/ + for(j = 0, estimated_ql_size = 0; j < info->numParams; ++j) + { 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(r = 0; r < control->numDecomp + 1; ++r) + { + resolution = ¶meter->resolution[r]; + nPrec = resolution->control.numPrecincts; - 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(m = 0; m < resolution->control.numSubbands; ++m) { - 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); + subband = &resolution->subband[m]; - /*--------------------------------------------------------*\ - ! 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]; + for(p = 0; p < resolution->control.numPrecincts; ++p) + { + for(cb = 0; cb < subband->precinct[p].control.numCodeblocks; ++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; - 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; + /*--------------------------------------------------------*\ + ! Loop over and find the first coding pass with a slope ! + ! value smaller than the threshold. ! + \*--------------------------------------------------------*/ + for(z = codeblock->encoded_block.Z; z >= 0 && codeblock->encoded_block.S[z] < threshold; --z); - if(z > 0) - { - estimated_ql_size += codeblock->encoded_block->L[z - 1]; - - if(z > 1 && (cp_contr[q_layer - 1] > 0)) + /*--------------------------------------------------------*\ + ! If no new coding passes, with regards to the last quali- ! + ! ty layer, are available, set the contribution for the ! + ! current equal to the previous quality layer. ! + \*--------------------------------------------------------*/ + if(z <= cp_contr[quality_layer - 1]) { - estimated_ql_size -= codeblock->encoded_block->L[cp_contr[q_layer - 1] - 1]; + cp_contr[quality_layer] = cp_contr[quality_layer - 1]; } - } - } + /*--------------------------------------------------------*\ + ! If new coding passes are avail., store the information ! + ! in the contribution list, add the additional length to ! + ! the q.l. size est. and set the empty header indicator. ! + \*--------------------------------------------------------*/ + else + { + cp_contr[quality_layer] = z; - /*--------------------------------------------------------*\ - ! 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; - } + estimated_ql_size += codeblock->encoded_block.L[z - 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(z > 1 && (cp_contr[quality_layer - 1] > 0)) + { + estimated_ql_size -= codeblock->encoded_block.L[cp_contr[quality_layer - 1] - 1]; + } - /*--------------------------------------------------------*\ - ! 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); + resolution->packet[quality_layer * nPrec + p].e = 1; + } - tagtree_set_value(subband->precinct[p].control.tag_inclusion, cb, l); - } - } - } + /*--------------------------------------------------------*\ + ! For final assembly... ! + \*--------------------------------------------------------*/ + if(est == 0) + { + /*--------------------------------------------------------*\ + ! ... and the first quality layer, set the value for the ! + ! number of non-significant, leading bitplanes in the ap- ! + ! propriate tagtree. ! + \*--------------------------------------------------------*/ + if(quality_layer == 0) + { + tagtree_set_value(&subband->precinct[p].control.tag_msbs, cb, codeblock->encoded_block.Kmsbs); + } + + /*--------------------------------------------------------*\ + ! ... and the last quality layer, set the last quality ! + ! layer, for which there exists a coding pass contribu- ! + ! tion from the current codeblock, in the appr. tagtree. ! + \*--------------------------------------------------------*/ + if(quality_layer + 1 == control->numLayers) + { + for(l = 0; (l < control->numLayers) && (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) + /*--------------------------------------------------------*\ + ! Loop over all precinct and evaluate and add packet head- ! + ! er sizes to the quality layer size estimation. If unsuc- ! + ! cessful, return an error flag to the function caller. ! + \*--------------------------------------------------------*/ + for(p = 0; p < resolution->control.numPrecincts; ++p) { - return -1; + estimated_ph_size = create_packet(field, resolution, p, quality_layer, est + 1); + + if(estimated_ph_size < 0) + { + return -1; + } + else + { + estimated_ql_size += estimated_ph_size; + } } - else - { - estimated_ql_size += estimated_ph_size; - } - - } - } - } - return estimated_ql_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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function loops over all user defined quality layers and iterates over the ! +! tile specific convex hull until a slope value is found that fits the quality ! +! layer bitrate. ! +! If an error occurres during packet parsing, the function returns an error flag ! +! to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Flag for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 29.04.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 26.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ static uchar -create_quality_layers(bwc_field *const field, bwc_tile *const tile) +create_quality_layers(bwc_field *const field) { - /*-----------------------*\ - ! 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 INT VARIABLES: ! + \*-----------------------*/ + uint64 header_size; + uint64 tile_size, tile_header_size; - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_gl_ctrl *control; - bwc_gl_inf *info; - bwc_tile_ctrl *tile_control; - bwc_tile_inf *tile_info; + int64 estimated_tile_size = 0; + int64 estimated_ql_size = 0; + int64 target_ql_size = 0; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(field); - assert(tile); + uint16 slope, lower_lim, upper_lim; + uint16 tmp; - /*--------------------------------------------------------*\ - ! Save the global and tile control and info structure to ! - ! temporary variables to make the code more readable. ! - \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; + uint8 l; - tile_control = &tile->control; - tile_info = &tile->info; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_gl_ctrl *control; + bwc_gl_inf *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); + bwc_tile_ctrl *tile_control; + bwc_tile_inf *tile_info; - /*--------------------------------------------------------*\ - ! 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; + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); - header_size = (uint64)ceilf((float)(main_header_size + tile_control->header_size) / control->nLayers); + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + control = &field->control; + info = &field->info; - /*--------------------------------------------------------*\ - ! Loop through and create all the user specified quality ! - ! layers. ! - \*--------------------------------------------------------*/ - for(l = 0; l < control->nLayers; ++l) - { + tile_control = &field->setup.tile.control; + tile_info = field->setup.tile.info; + + /*--------------------------------------------------------*\ + ! Evaluate the size of the current tile and the size im- ! + ! pact of the global and tile codestream header on a sin- ! + ! gle 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->numParams; + + tile_header_size = 20 + (info->numParams * 16); + + header_size = (uint64)ceilf((float)((control->main_header_size / control->numTiles) + + tile_header_size) / control->numLayers); + + /*--------------------------------------------------------*\ + ! Loop over and assemble all user spec. quality layers. ! + \*--------------------------------------------------------*/ + for(l = 0; l < control->numLayers && l < 10; ++l) + { /*--------------------------------------------------------*\ - ! Calculate the size of target size of quality layer l. ! + ! Evaluate the target size of the next quality layer and ! + ! find the corresponding convex slope value. ! \*--------------------------------------------------------*/ 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; + { + /*--------------------------------------------------------*\ + ! Initialize the sliding limits, slope value and temporary ! + ! variable and loop over the complex hull until a the slid-! + ! ing limits have converged on a fitting slope value. ! + \*--------------------------------------------------------*/ + lower_lim = tile_control->slope_min; + upper_lim = tile_control->slope_max; + slope = lower_lim; + tmp = lower_lim; - while(slope_min < slope_max) - { - slope = (slope_max + slope_min) >> 1; - - estimated_ql_size = create_quality_layer(field, tile, slope, l, 1); + while(lower_lim < upper_lim) + { + /*--------------------------------------------------------*\ + ! Place the new slope value in the middle of the sliding ! + ! limits and evaluate the corresponding quality layer size.! + \*--------------------------------------------------------*/ + slope = (upper_lim + lower_lim) >> 1; - if(estimated_ql_size >= 0) - { - estimated_ql_size += estimated_tile_size + header_size; - } - else - { - return 1; + estimated_ql_size = create_quality_layer(field, slope, l, 1); + + /*--------------------------------------------------------*\ + ! If no error has been encountered, add the size of the ! + ! previous quality layers and header impact to the esti- ! + ! mated size. If not, return with an error flag. ! + \*--------------------------------------------------------*/ + if(estimated_ql_size >= 0) + { + estimated_ql_size += estimated_tile_size + header_size; + } + else + { + return EXIT_FAILURE; + } + /*--------------------------------------------------------*\ + ! If the est. is larger than the target size, move the low-! + ! er limit up to the slope value. Artificial convergence ! + ! is enforced if lower_lim == slope. ! + \*--------------------------------------------------------*/ + if(estimated_ql_size > target_ql_size) + { + if(lower_lim == slope) + { + upper_lim = lower_lim; + } + lower_lim = slope; + } + /*--------------------------------------------------------*\ + ! If the est. is larger than the target size, move the up- ! + ! er limit down to the slope value. Artificial convergence ! + ! is enforced if upper_lim == slope. ! + \*--------------------------------------------------------*/ + else if(estimated_ql_size < target_ql_size) + { + if(upper_lim == slope) + { + lower_lim = upper_lim; + } + upper_lim = slope; + tmp = slope; + } + /*--------------------------------------------------------*\ + ! If the estimated size is equal to the target size, con- ! + ! vergence has been reached. Set the sliding limits accord-! + ! ingly to stop the search. ! + \*--------------------------------------------------------*/ + else + { + upper_lim = slope; + lower_lim = slope; + } } - if(estimated_ql_size > target_ql_size) + /*--------------------------------------------------------*\ + ! If the estimation is larger than the target, move the ! + ! slope up to the last valid upper limit. ! + \*--------------------------------------------------------*/ + if(estimated_ql_size > target_ql_size) { - if(slope_min == slope) - { - slope_max = slope; - } - slope_min = slope; + slope = MAX(tmp, tile_control->slope_min); } - 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; - } + { + slope = 0; + } - estimated_ql_size = create_quality_layer(field, tile, slope, l, 0); + /*--------------------------------------------------------*\ + ! Assemble the final quality layer. If successful, add its ! + ! bytes, including the header impact, to the tile size es- ! + ! timation. ! + \*--------------------------------------------------------*/ + estimated_ql_size = create_quality_layer(field, slope, l, 0); if(estimated_ql_size >= 0) - { - estimated_tile_size += estimated_ql_size + header_size; - } + { + estimated_tile_size += estimated_ql_size + header_size; + } else - { - return 1; - } - } - return 0; + { + return EXIT_FAILURE; + } + } + return EXIT_SUCCESS; } -/************************************************************************************************************\ -|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || -|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || -|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || -|| || -\************************************************************************************************************/ -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ + +/**********************************************************************************************************************\ +|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || +|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\**********************************************************************************************************************/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function defines the rate control protion of the entropy encoding stage. ! +! The quality layers are evaluated according to the bitrates defined by the user. ! +! These layers are assembled into datapackets which are then flushed to the code- ! +! stream. Once final assembly has been successful, all encoded blocks are proper- ! +! ly deallocated end reset for the next comprssion run. ! +! If an error occurres during packet parsing, the function returns an error flag ! +! to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Flag for error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 12.06.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 26.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ uchar -t2_encode(bwc_field *const field, bwc_tile *const tile) +t2_encode(bwc_field *const field) { - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(field); - assert(tile); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); - /*--------------------------------------------------------*\ - ! Create the quality layers according to the bitrate val- ! - ! ues provided by the user. ! - \*--------------------------------------------------------*/ - if(create_quality_layers(field, tile)) - { - return 1; - } + /*--------------------------------------------------------*\ + ! Create the quality layers according to the bitrate val- ! + ! ues provided by the user. ! + \*--------------------------------------------------------*/ + if(create_quality_layers(field) == EXIT_FAILURE) + { + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! Create the data packets according to the quality layers ! - ! evaluated in the previous step. ! - \*--------------------------------------------------------*/ - if(create_packets(field, tile)) - { - return 1; - } + /*--------------------------------------------------------*\ + ! Create the data packets according to the quality layers ! + ! evaluated in the previous step. ! + \*--------------------------------------------------------*/ + if(create_packets(field)) + { + return EXIT_FAILURE; + } - return 0; + return EXIT_SUCCESS; } -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function is used to parse and load a codestream packet from file into the ! +! bwc field structure. ! +! If an error occurres during packet parsing, the function returns an error flag ! +! to the function caller. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! field bwc_field* - Codec control structure. ! +! ! +! packet bwc_packet* - Structure defining a bwc packet. ! +! ! +! body_size unsigned int(64 bit) - Size of the remaining bwc code- ! +! stream. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! unsigned char - Returns an unsigned char for ! +! error handling. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 29.04.2019 Patrick Vogler B87D120 V 0.1.0 Function created. ! +! 26.06.2020 Patrick Vogler B87E7E4 V 0.1.0 Clean up. ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ uchar -parse_packet(bwc_field *const field, bwc_tile *const tile, - bwc_packet *const packet, - uint64 const body_size) +parse_packet(bwc_field *const field, + 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 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 STRUCTS: ! + \*-----------------------*/ + bwc_resolution *resolution; + bwc_precinct *precinct; + bwc_codeblock *codeblock; + bwc_encoded_blk *encoded_block; + bwc_stream *header; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(field); - assert(tile); - assert(packet); + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(field); + assert(packet); - resolution = &tile->parameter[packet->c].resolution[packet->r]; + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + resolution = &field->setup.tile.parameter[packet->p].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) - { + /*--------------------------------------------------------*\ + ! Initialize the stream used for packet header parsing and ! + ! extract the codeblock contribution marker. ! + \*--------------------------------------------------------*/ + header = init_stream(packet->header.memory, body_size, 'd'); + if(header == NULL) + { // memory allocation error - return 1; - } + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! Extract the codeblock contribution marker from the code- ! - ! stream. ! - \*--------------------------------------------------------*/ - packet->e = bwc_get_bit(header); + packet->e = 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]; + /*--------------------------------------------------------*\ + ! Proceed with packet parsing if it provides a contribu- ! + ! to the current quality layer. ! + \*--------------------------------------------------------*/ + if(packet->e != 0) + { + for(m = 0; m < resolution->control.numSubbands; ++m) + { + precinct = &resolution->subband[m].precinct[packet->pr]; - 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) + for(cb = 0; cb < precinct->control.numCodeblocks; ++cb) { - /*--------------------------------------------------------*\ - ! 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); + /*--------------------------------------------------------*\ + ! 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; - /*--------------------------------------------------------*\ - ! 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; + /*--------------------------------------------------------*\ + ! Initialize the additional coding passes present in the ! + ! packet body. ! + \*--------------------------------------------------------*/ + delta_z = 0; - while(decode_tagtree(precinct->control.tag_msbs, header, k++, cb)); + /*--------------------------------------------------------*\ + ! If no contribution by the current codeblock has previous-! + ! ly been made, ... ! + \*--------------------------------------------------------*/ + if(cp_contr[packet->l - 1] == 0) + { + /*--------------------------------------------------------*\ + ! ... decode the inclusion tagtree and, if a packet input ! + ! is available, the leading non-significant bitplane tag- ! + ! tree for the current codeblock. ! + \*--------------------------------------------------------*/ + decode_tagtree(&precinct->control.tag_inclusion, header, packet->l + 1, cb); - codeblock->encoded_block->Kmsbs = tagtree_get_value(precinct->control.tag_msbs, cb); - } + 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); + } + } + /*--------------------------------------------------------*\ + ! If a contribution has already been made, get the flag ! + ! signals if new coding passes are available from the ! + ! header stream. ! + \*--------------------------------------------------------*/ + else + { + delta_z = get_bit(header); + } + + /*--------------------------------------------------------*\ + ! Initialize the codeblock contribution with the previous ! + ! quality layer. ! + \*--------------------------------------------------------*/ + cp_contr[packet->l] = cp_contr[packet->l - 1]; + + /*--------------------------------------------------------*\ + ! If new coding passes are available, ... ! + \*--------------------------------------------------------*/ + if(delta_z != 0) + { + /*--------------------------------------------------------*\ + ! decode the new coding passes, update the codeblock con- ! + ! bution and maximum number of available coding passes and ! + ! decode the corresponding lengths. ! + \*--------------------------------------------------------*/ + decode_delta_z(header, delta_z); + + cp_contr[packet->l] += delta_z; + codeblock->encoded_block.Z = cp_contr[packet->l]; + + decode_length(header, codeblock, packet->l); + } } - else + } + } + /*--------------------------------------------------------*\ + ! If no contribution is available, iterate over all code- ! + ! blocks in all subbands and initialize the current quali- ! + ! layer with the previous q.l. coding pass contributions. ! + \*--------------------------------------------------------*/ + else + { + for(m = 0; m < resolution->control.numSubbands; ++m) + { + precinct = &resolution->subband[m].precinct[packet->pr]; + + for(cb = 0; cb < precinct->control.numCodeblocks; ++cb) { - /*--------------------------------------------------------*\ - ! 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); + codeblock = &precinct->codeblock[cb]; + cp_contr = codeblock->control.cp_contr; + + cp_contr[packet->l] = cp_contr[packet->l - 1]; } + } + } - - /*--------------------------------------------------------*\ - ! 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) - { + /*--------------------------------------------------------*\ + ! If not already evaluated, safe the packet header size in ! + ! its structure and set up the packet body packed stream ! + ! with the current header stream memory handle. ! + \*--------------------------------------------------------*/ + if(packet->header.size == 0) + { 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) - { + if(packet->body.memory == NULL) + { packet->body.access = - packet->body.memory = get_access(header); - } + packet->body.memory = GET_ACCESS(header); + } - /*--------------------------------------------------------*\ - ! Free the packet header stream. ! - \*--------------------------------------------------------*/ - free(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 error resilience is active, check that the codestream ! + ! includes the end of packet header (EOH) marker. If true, ! + ! augment the packet stream. If not, return an error flag. ! + \*--------------------------------------------------------*/ + if(field->control.resilience != 0) + { if(packet->body.memory[0] != 0xFF || packet->body.memory[1] != 0x92) - { - /*--------------------------------------------------------*\ - ! ... If not, return to the function caller with an error ! - ! marker. ! - \*--------------------------------------------------------*/ - return 1; - } + { + return EXIT_FAILURE; + } 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; - } - } + { + 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]; + /*--------------------------------------------------------*\ + ! If available, load the packet body into memory. ! + \*--------------------------------------------------------*/ + if(packet->e != 0) + { + for(m = 0; m < resolution->control.numSubbands; ++m) + { + precinct = &resolution->subband[m].precinct[packet->pr]; - 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]) + for(cb = 0; cb < precinct->control.numCodeblocks; ++cb) { - /*--------------------------------------------------------*\ - ! 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; + /*--------------------------------------------------------*\ + ! Save frequently used variables/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; - /*--------------------------------------------------------*\ - ! 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; - } + /*--------------------------------------------------------*\ + ! If additional coding passes contributions are available ! + ! for the current quality layer... ! + \*--------------------------------------------------------*/ + if(cp_contr[packet->l] > cp_contr[packet->l - 1]) + { + /*--------------------------------------------------------*\ + ! ... evaluate the start and end points as well as the con-! + ! tribution size, ... ! + \*--------------------------------------------------------*/ + 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; - /*--------------------------------------------------------*\ - ! Copy the data to the encoded block structure. ! - \*--------------------------------------------------------*/ - memcpy(codeblock->encoded_block->data + start, packet->body.access, size); + /*--------------------------------------------------------*\ + ! ... reallocate the encoded codeblock memory block to ac- ! + ! commodate the coding pass contribution, ... ! + \*--------------------------------------------------------*/ + encoded_block->data = realloc(encoded_block->data, end + size); + if(encoded_block->data == NULL) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return EXIT_FAILURE; + } - /*--------------------------------------------------------*\ - ! 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; + /*--------------------------------------------------------*\ + ! ... copy the data to the encoded block structure and ... ! + \*--------------------------------------------------------*/ + memcpy(codeblock->encoded_block.data + start, packet->body.access, size); + + /*--------------------------------------------------------*\ + ! ... advance the packet body access pointer to the next ! + ! coding 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; + /*--------------------------------------------------------*\ + ! Evaluate the packet size and return to the function ! + ! caller. ! + \*--------------------------------------------------------*/ + packet->size = packet->header.size + packet->body.size; + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index b05db0f..8042067 100755 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -1,93 +1,64 @@ -#*====================================================================================================================*# -#| |# -#| /$$$$$$$ /$$ /$$ /$$ /$$ |# -#| | $$__ $$|__/ | $$ /$ | $$| $$ |# -#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# -#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# -#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# -#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# -#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# -#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# -#| /$$ \ $$ | $$ |# -#| | $$$$$$/ | $$ |# -#| \______/ |__/ |# -#| 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. |# -#| |# -#*====================================================================================================================*# -#*--------------------------------------------------------*# +#*================================================================================================*# +#| |# +#| /$$$$$$$ /$$ /$$ /$$ /$$ |# +#| | $$__ $$|__/ | $$ /$ | $$| $$ |# +#| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |# +#| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ |# +#| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ |# +#| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ |# +#| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ |# +#| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ |# +#| /$$ \ $$ | $$ |# +#| | $$$$$$/ | $$ |# +#| \______/ |__/ |# +#| |# +#| DESCRIPTION: |# +#| ------------ |# +#| |# +#| Defines the cmake script for the BigWhoop command line tool. |# +#| |# +#| -------------------------------------------------------------------------------------------- |# +#| 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. |# +#| |# +#*================================================================================================*# +#----------------------------------------------------------# # 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) +#----------------------------------------------------------# +add_executable(bwccmd bwccmdl.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) +#----------------------------------------------------------# +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 index e2fc98e..b994920 100755 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -12,73 +12,33 @@ || | $$$$$$/ | $$ || || \______/ |__/ || || || -|| 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. || +|| DESCRIPTION: || +|| ------------ || +|| This is a simple command line tool that uses the Big Whoop library to (de)compress a || +|| 2- to 4-dimensional IEEE 754 floating point array. For further information use the || +|| --help (-h) argument in the command-line or consult the appropriate 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. || +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || || || -|| - output - Output - Output file that the com- || -|| pressed bitstream, for a com- || -|| pression run, or reconstructed || -|| dataset, for a decompression || -|| run, is written to. || +|| Redistribution and use in source and binary forms, with or without modification, are permitted provided that the || +|| following conditions are met: || || || -|| FUNCTIONS: || -|| ---------- || +|| (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the || +|| following disclaimer. || || || -|| PRIVATE: PUBLIC: || -|| -------- ------- || -|| - get_digit_sep - main || -|| - get_size || -|| - get_dimension || -|| - get_prog_ord || -|| - get_quant_style || +|| (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. || || || -|| 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. || +|| 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. || || || \*====================================================================================================================*/ /**********************************************************************************************************************\ @@ -2852,9 +2812,9 @@ main(int argc, if((temp != NULL) && (temp->count == 1)) { if(strcmp(temp->lit_opt[0], "NONE")) - bwc_set_quantization_style(field, bwc_qt_none); + bwc_set_quant_style(field, bwc_qt_none); else - bwc_set_quantization_style(field, bwc_qt_derived); + bwc_set_quant_style(field, bwc_qt_derived); } /*--------------------------------------------------------*\ @@ -2863,7 +2823,7 @@ main(int argc, temp = retrieve_arg(args, "quantisation_step_size"); if((temp != NULL) && (temp->count == 1)) { - bwc_set_quantization_step_size(field, temp->num_opt[0]); + bwc_set_quant_step_size(field, temp->num_opt[0]); } /*--------------------------------------------------------*\ diff --git a/src/tools/get_hash.c b/src/tools/get_hash.c deleted file mode 100755 index 360023a..0000000 --- a/src/tools/get_hash.c +++ /dev/null @@ -1,154 +0,0 @@ -/*==================================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| 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 diff --git a/src/tools/test.c b/src/tools/test.c new file mode 100644 index 0000000..4b4b95b --- /dev/null +++ b/src/tools/test.c @@ -0,0 +1,640 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/************************************************************************************************************\ +|| _ _ ____ ____ ____ ____ ____ || +|| |\/| |__| | |__/ | | [__ || +|| | | | | |___ | \ |__| ___] || +|| || +\************************************************************************************************************/ +/*----------------------------------------------------------------------------------------------------------*\ +! 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 remove_deliminator(arg, end, delim) \ +{ \ + for(end = arg; *end; end++) \ + *end = (*end == delim ? ' ' : *end); \ +} + +// need to mention a version string. +const char *argp_program_version = "bwc 0.1.0"; + +// documentation string that will be displayed in the help section. +static char doc[] = "\n"\ + "bwc is a simple command line tool that leverages the Big Whoop library to (de)compress a 2- to 4-dimensional IEEE 754 " + "floating point array.\n"\ + "\n"\ + "Available use cases:\n"\ + "\n"\ + " Compression: bwc -c [INPUT] [OPTIONS]\n"\ + " Decompression: bwc -d [INPUT] [OPTIONS]\n"\ + " Analysis: bwc -a [INPUT] -r [REFERENCE]\n"\ + " Information: bwc -h [INPUT]\n"\ + "\n"\ + "Valid Option Values:\n"\ + "\n" + " String that defines: input = path/to/an/input/file.\n" + " String that defines: output = path/to/an/output/file.\n" + "\n" + " Single numerical value: num = *.\n" + " One or more numerical values seperated by commas:\n" + " narr = *,*,...\n" + "\n" + " Numerical values that can be specified globally or for\n" + " all spacial and temporal directions individually:\n" + " ndir = * or ndir = x/y/z/ts.\n"; + /*"\n" + " Single string.\n" + " One or more strings seperated by commas: sarr = *,*,...\n" + " Strings that can be specified globally or for all\n" + " spacial and temporal directions individually:\n" + " sdir = * or sdir = x/y/z/ts.\n"*/ + +// email address for bug reporting. +const char *argp_program_bug_address = "hpcpvogl@hlrs.de"; + +// cli argument availble options. +static struct argp_option options[] = { +//____________________________________________________________________________________________________________________________________________________| +//====================================================================================================================================================| +{0, 0, 0, 0, " [FILE OPTIONS]\n", 1}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"analysis", 'a', "", 0, "Analyze Peak Signal to Noise Ratio (PSNR) and Mean " + "Square Error (MSE) between input and reference file.\n",1}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"comp", 'c', "", 0, "Compress a numerical dataset.", 1}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"decomp", 'd', "", 0, "Decompress a BigWhoop file.", 1}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"header", 'h', "", 0, "Display the header information of a BigWhoop file.\n", 1}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"output", 'o', "", 0, "Defines output file.", 1}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"reference", 'r', "", 0, "Reference file used for PSNR and MSE calculation.", 1}, +//====================================================================================================================================================| + +//____________________________________________________________________________________________________________________________________________________| +//====================================================================================================================================================| +{0, 0, 0, 0, " [LITERAL OPTIONS]\n", 2}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"erresilience", 'e', 0, OPTION_HIDDEN, "Instrument bitstream to allow for error resilient de" + "coding of compressed dataset.\n", 2}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"stream", 's', 0, OPTION_HIDDEN, "Stream data to and from /.", 2}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"verbose", 'v', 0, 0, "Display compression statistics and applied compression " + "parameters.", 2}, +//====================================================================================================================================================| + +//____________________________________________________________________________________________________________________________________________________| +//====================================================================================================================================================| +{0, 0, 0, 0, " [NUMERICAL OPTIONS]\n", 3}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"bitrate", 'b', "", 0, "Quality layers present in the code stream as a func" + "tion of the average bits per data-point. Accepts real " + "numbers in the range of 0 < * < 64.\n", 3}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"codeblock", 'B', "", 0, "Codeblock size in log2 format. Accepts natural numbers " + "in the range of 1 <= * <= 10 with the sum having to " + "lie in the range of 4 < sum* < 20.\n", 3}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"decomplvl", 'D', "", 0, "Number of wavelet decompositions applied to the data " + "arrays. Accepts natural numbers in the range of 1 <= " + "* <= 63.\n", 3}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"layer", 'l', "", OPTION_HIDDEN, "Quality layer used to reconstruct the numerical data" + "set. Accepts natural numbers in the range of 0 < * <= " + "number_of_quality_layers.\n", 3}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"nthreads", 'n', "", 0, "Number of OpenMP threads used to (de)compress the " + " file. Accepts natural numbers in the range of " + "1 <= * <= 255.\n", 3}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"precinct", 'p', "", OPTION_HIDDEN, "Precinct size in log2 format. Accepts natural numbers " + "in the range of 1 <= * <= 15.\n", 3}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"qstep", 'q', "", OPTION_HIDDEN, "Quantization step size applied to the wavelet coeff" + "icients. Accepts real numbers in the range of 0 < * " + "< 2.\n", 3}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"qformat", 'Q', "", 0, "Fractional bits of the Q number format used in the " + "floating-to-fixed point transfomration. Accepts " + "natural numbers in the range of 1 <= * <= 62.\n", 3}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"compratio", 'R', "", 0, "Target ratio between the uncompresssed and com- " + "pressed file size. Accepts positive real numbers.\n", 3}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"tile", 't', "", 0, "Size of tiles the dataset is subdivided into. Accepts " + "natural numbers in the range of 16 <= * <= domain " + "size.", 3}, +//====================================================================================================================================================| + +//____________________________________________________________________________________________________________________________________________________| +//====================================================================================================================================================| +//{0, 0, 0, 0, " [NUMERICAL OPTIONS]\n", 4}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{"wkernels", 'k', "", OPTION_HIDDEN, "Wavelet kernels applied along spatial and temporal " + "aixs. Accepts the strings CDF, LeGall and Haar.", 4}, +//---------------------------|-----|---------------------------|--------------------------|-------------------------------------------------------|---| +{0} +}; + + +typedef struct +{ + char *analysis; + char *comp; + char *decomp; + char *header; + char *output; + char *reference; + + unsigned char erresilience; + unsigned char stream; + unsigned char verbose; + + uint8_t nthreads; + uint8_t qformat; + uint8_t layer; + + uint16_t compratio; + + double qstep; + + uint8_t codeblock[4]; + uint8_t decomplvl[4]; + uint8_t precinct[4]; + uint64_t tile[4]; + double bitrate[16]; + + char *wkernels[4]; +}arguments; + + +/*--------------------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function will parse one option at a time and depending upon the option ! +! flag, it will set the corresponding value in struct arguments. ! +! ! +! PARAMETERS: ! +! ----------- ! +! Variable Type Description ! +! -------- ---- ----------- ! +! | | ! +! key int - Key representing a command ! +! line option. ! +! ! +! arg char* - String associated with the ! +! supplied key. ! +! ! +! state argp_state* - Argp structure used to store ! +! the option value. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! error_t - Arguments/options linked list ! +! for the bwc command-line tool. ! +! ! +! DEVELOPMENT HISTORY: ! +! -------------------- ! +! ! +! Date Author Change Id Release Description ! +! ---- ------ --------- ------- ----------- ! +! 16.02.2019 Patrick Vogler B87D120 V 0.1.0 function created ! +! ! +\*--------------------------------------------------------------------------------------------------------------------*/ +static error_t +parse_opt(int key, + char *arg, + struct argp_state *state) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64_t buff_LL; + uint64_t multiplier; + + uint16_t buffI; + + uint8_t i; + uint8_t length, shift; + + + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + double buff_D; + + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + char *end; + + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + // bwc_field *field; + + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + //assert(arg); + //assert(state); + + /*--------------------------------------------------------*\ + ! Save frequently used variables/structures to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + //field = state->input; + + + switch(key) + { + case 'c': + { + field->flag = SETUP_CMP; + field->data.flag = DATA_IN; + field->codestream.flag = CS_OUT; + + break; + } + case 'd': + { + field->flag = SETUP_DCP; + field->data.flag = DATA_OUT; + field->codestream.flag = CS_IN; + + break; + } + case 'a': + { + arguments->analysis = arg; + break; + } + case 'h': + { + arguments->header = arg; + break; + } + case 'o': + { + arguments->output = arg; + break; + } + case 'r': + { + arguments->reference = arg; + break; + } + case 's': + { + arguments->stream = 1; + break; + } + case 'v': + { + arguments->stream = 1; + break; + } + case 'b': + { + remove_deliminator(arg, end, ','); + + for(buff_D = strtod(arg, &end), i = 0; arg != end && i < 16; + buff_D = strtod(arg, &end), i++) + { + arg = end; + if (errno == ERANGE) + { + printf("range error, got "); + errno = 0; + } + + if(buff_D > 0 && buff_D < 64) + { + arguments->bitrate[i] = (double) buff_D; + } + else + { + argp_error(state, "The specified bitrate (%f) is " + "out of the supported range.\n", buff_D); + } + } + } + case 'B': + { + remove_deliminator(arg, end, '/'); + + for(buff_LL = strtoll(arg, &end, 10), i = 0; arg != end && i < 4; + buff_LL = strtoll(arg, &end, 10), i++) + { + arg = end; + if (errno == ERANGE) + { + printf("range error, got "); + errno = 0; + } + + if(buff_LL > 1 && buff_LL < 10) + { + arguments->codeblock[i] = (uint8_t) buff_LL; + } + else + { + argp_error(state, "The specified codeblock size (%ld) " + "is out of the supported range.\n", buff_LL); + } + } + + if(i == 1) + { + arguments->codeblock[1] = + arguments->codeblock[2] = + arguments->codeblock[3] = arguments->codeblock[0]; + } + else if(i != 4) + { + argp_error(state, "The codeblock argument expects either a " + "single global or 4 dirctional values\n"); + } + + if(((arguments->codeblock[0] + arguments->codeblock[1] + + arguments->codeblock[2] + arguments->codeblock[3]) < 4) || + ((arguments->codeblock[0] + arguments->codeblock[1] + + arguments->codeblock[2] + arguments->codeblock[3]) > 20)) + { + argp_error(state, "The sum of the specified codeblock sizes " + "is outside of the supported range\n"); + } + break; + } + case 'R': + { + arguments->compratio = (uint8_t)strtoll(arg, &end, 10); + printf("%d\n", arguments->compratio); + break; + } + case 'D': + { + remove_deliminator(arg, end, '/'); + + for(buff_LL = strtoll(arg, &end, 10), i = 0; arg != end && i < 4; + buff_LL = strtoll(arg, &end, 10), i++) + { + arg = end; + if (errno == ERANGE) + { + printf("range error, got "); + errno = 0; + } + + if(buff_LL >= 1 && buff_LL <= 63) + { + arguments->codeblock[i] = (uint8_t) buff_LL; + } + else + { + argp_error(state, "The specified codeblock size (%ld) " + "is out of the supported range.\n", buff_LL); + } + } + + if(i == 1) + { + arguments->codeblock[1] = + arguments->codeblock[2] = + arguments->codeblock[3] = arguments->codeblock[0]; + } + else if(i != 4) + { + argp_error(state, "The codeblock argument expects either a " + "single global or 4 dirctional values\n"); + } + break; + } + case 'n': + { + buff_LL = strtoll(arg, &end, 10); + if((buff_LL < 1) || (buff_LL > 255)) + { + argp_error(state, "The number of OpenMP threads specified" + "is out of the supported range.\n"); + } + else + { + arguments->nthreads = (uint8_t)buff_LL; + } + break; + } + case 'l': + { + printf("l\n"); + break; + } + case 'k': + { + printf("k\n"); + break; + } + case 'q': + { + printf("q\n"); + break; + } + case 'Q': + { + printf("Q\n"); + break; + } + case 'e': + { + printf("e\n"); + break; + } + case 't': + { + printf("t\n"); + break; + } + case 'p': + { + printf("p\n"); + break; + } + + case ARGP_KEY_ARG: + + // Too many arguments. + if(state->arg_num > 1) + argp_usage(state); + break; + + case ARGP_KEY_END: + if(!((arguments->analysis != NULL) && (arguments->comp == NULL) + && (arguments->decomp == NULL) + && (arguments->header == NULL) + && (arguments->output == NULL) + && (arguments->reference != NULL)) && + !((arguments->comp != NULL) && (arguments->analysis == NULL) + && (arguments->decomp == NULL) + && (arguments->header == NULL) + && (arguments->reference == NULL)) && + !((arguments->decomp != NULL) && (arguments->analysis == NULL) + && (arguments->comp == NULL) + && (arguments->header == NULL) + && (arguments->reference == NULL)) && + !((arguments->header != NULL) && (arguments->analysis == NULL) + && (arguments->comp == NULL) + && (arguments->decomp == NULL) + && (arguments->output == NULL) + && (arguments->reference == NULL))) + { + argp_error(state, "The User supplied options do not fit the" + "supported use cases.\n"); + } + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return EXIT_SUCCESS; +} + + + +// initialize the argp struct. Which will be used to parse and use the args. +static struct argp argp = {options, parse_opt, 0, doc}; + + + /*--------------------------------------------------------*\ + 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"); + }*/ + + +int main(int argc, char *argv[]) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_field field; + + /*--------------------------------------------------------*\ + ! Allocate the field structure and set the appropriate ! + ! flags per the mode supplied by the function caller. ! + \*--------------------------------------------------------*/ + memset(field, 0, sizeof(bwc_field)); + + // parse the cli arguments. + argp_parse(&argp, argc, argv, 0, 0, &field); + + //printf("ARG1: %s", arguments.args[0]); + //printf("\nVERBOSE: %s", arguments.verbose? "yes" : "no"); + //printf("\nOption1: %s", arguments.option1); + printf("\n"); +}