From 6d5dc06446eeabea8cbc6edf66682d299f5148cb Mon Sep 17 00:00:00 2001 From: Patrick Vogler Date: Mon, 28 Oct 2024 11:04:18 +0100 Subject: [PATCH 01/21] Modified eas3 interface to decouple it from the command line tool. --- include/interfaces/reader/eas3.h | 12 +++++++++ src/interfaces/reader/eas3.c | 44 +++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/include/interfaces/reader/eas3.h b/include/interfaces/reader/eas3.h index 00686f9..c7d647b 100644 --- a/include/interfaces/reader/eas3.h +++ b/include/interfaces/reader/eas3.h @@ -347,6 +347,18 @@ || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || || || \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! This function deallocates the data structure used to store an numerical dataset ! + ! 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 + eas3_free_data(eas3_data* data); + /*----------------------------------------------------------------------------------------------------------*\ ! FUNCTION NAME: bwc_data* read_eas3(const char* const filename) ! ! -------------- ! diff --git a/src/interfaces/reader/eas3.c b/src/interfaces/reader/eas3.c index baacce0..7581118 100644 --- a/src/interfaces/reader/eas3.c +++ b/src/interfaces/reader/eas3.c @@ -76,7 +76,25 @@ #include #include "eas3.h" -#include "bwccmdl.h" + + +/************************************************************************************************************\ +|| _ _ ____ ____ ____ ____ ____ || +|| |\/| |__| | |__/ | | [__ || +|| | | | | |___ | \ |__| ___] || +|| || +\************************************************************************************************************/ +#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" /************************************************************************************************************\ || ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || @@ -213,18 +231,20 @@ endian_conversion(void *value, void eas3_free_data(eas3_data* data) { - if(data) + if(data != NULL) { - //if(data->aux) - //{ - //free(data->aux->memory); - //data->aux->access = NULL; - //data->aux->position = 0; - //data->aux->size = 0; - // TODO: remove - //data->aux->L = 0; - //} - //free(data->aux); + if (data->param_names != NULL) + free(data->param_names); + + if (data->field.d != NULL) + free(data->field.d); + + if (data->field.f != NULL) + free(data->field.f); + + if(data->aux.ptr != NULL) + free(data->aux.ptr); + free(data); } } -- 2.45.2 From 90645bcf1b10a1554a7b812782f6c2cf9d87536c Mon Sep 17 00:00:00 2001 From: Patrick Vogler Date: Mon, 28 Oct 2024 11:05:34 +0100 Subject: [PATCH 02/21] Implemented the arg_parse function for bwccmdl and added preliminary mode setting functionality for main. --- include/tools/bwccmdl.h | 350 ------------ src/tools/bwccmdl.c | 1127 ++++++++++++++++++++++++++++----------- 2 files changed, 821 insertions(+), 656 deletions(-) delete mode 100644 include/tools/bwccmdl.h diff --git a/include/tools/bwccmdl.h b/include/tools/bwccmdl.h deleted file mode 100644 index be53e0b..0000000 --- a/include/tools/bwccmdl.h +++ /dev/null @@ -1,350 +0,0 @@ -/*====================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| DESCRIPTION: || -|| ------------ || -|| This is a simple command line tool that uses the Big Whoop library to (de)com- || -|| press a 2- to 4-dimensional IEEE 754 floating point array. For further infor- || -|| mation use the --help (-h) argument in the command-line or consult the appro- || -|| priate README file. || -|| || -|| STRUCTS: || -|| -------- || -|| DESCRIPTION NEEDED. || -|| || -|| DEVELOPMENT HISTORY: || -|| -------------------- || -|| || -|| Date Author Change Id Release Description || -|| ---- ------ --------- ------- ----------- || -|| 13.10.2017 Patrick Vogler B87D120 V 0.1.0 source file created || -|| 26.11.2020 Patrick Vogler B87E7E4 V 0.1.0 Command line tool refac- || -|| tored. || -|| || -|| || -|| ------------------------------------------------------------------------------------------------------ || -|| || -|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || -|| || -|| Redistribution and use in source and binary forms, with or without modification, are permitted || -|| provided that the following conditions are met: || -|| || -|| (1) Redistributions of source code must retain the above copyright notice, this list of || -|| conditions and the following disclaimer. || -|| || -|| (2) Redistributions in binary form must reproduce the above copyright notice, this list || -|| of conditions and the following disclaimer in the documentation and/or other materials || -|| provided with the distribution. || -|| || -|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED || -|| WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A || -|| PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR || -|| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT || -|| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS || -|| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR || -|| TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF || -|| ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || -|| || -\*====================================================================================================================*/ -#ifndef BWC_CMDL_H -#define BWC_CMDL_H - - /********************************************************************************************************************\ - || _ _ _ ____ _ _ _ ___ ____ || - || | |\ | | | | | | \ |___ || - || | | \| |___ |___ |__| |__/ |___ || - || || - \********************************************************************************************************************/ - #include - - /********************************************************************************************************************\ - || _ _ ____ ____ ____ ____ ____ || - || |\/| |__| | |__/ | | [__ || - || | | | | |___ | \ |__| ___] || - || || - \********************************************************************************************************************/ - /*------------------------------------------------------------------------------------------------------------------*\ - ! DESCRIPTION: ! - ! ------------ ! - ! ! - ! These macros define minimum and maximum operators as well as an operator used ! - ! to evaluate the size of an array. ! - ! ! - ! MACROS: ! - ! ------- ! - ! Name Description ! - ! ---- ----------- ! - ! MAX(x, y) - Returns the maximum value of ! - ! two values. ! - ! ! - ! MIN(x, y) - Returns the minimum value of ! - ! two values. ! - ! ! - ! GET_LEN(x) - Returns the size of an array. ! - ! ! - ! DEVELOPMENT HISTORY: ! - ! -------------------- ! - ! ! - ! Date Author Change Id Release Description ! - ! ---- ------ --------- ------- ----------- ! - ! 21.03.2018 Patrick Vogler B87D120 V 0.1.0 macros created ! - ! 16.09.2019 Patrick Vogler B87E7E4 V 0.1.0 Added GET_LEN(X) macro. ! - ! ! - \*------------------------------------------------------------------------------------------------------------------*/ - #define MAX(x, y) (((x) < (y))?(y):(x)) - #define MIN(x, y) (((x) > (y))?(y):(x)) - - /*------------------------------------------------------------------------------------------------------------------*\ - ! DESCRIPTION: ! - ! ------------ ! - ! ! - ! These Constants define codestream markers used to create the embedded code- ! - ! stream. ! - ! ! - ! MACROS: ! - ! ------- ! - ! Name Description ! - ! ---- ----------- ! - ! SOC - Start of code-stream ! - ! SGI - Global data-set information ! - ! SGC - Global control parameters ! - ! SGR - Global register containing tile ! - ! bitstream size information ! - ! SAX - Auxiliary data-set information ! - ! TLM - Packet lengths: main header ! - ! PLM - Packet lengths: tile-part ! - ! PPM - Quantization default ! - ! COM - Comment ! - ! EOH - End of header ! - ! PLT - Packed packet headers: main header ! - ! PPT - Packed packet headers: tile-part ! - ! SOT - Start of tile ! - ! SOP - Start of packet ! - ! EPH - End of packet header ! - ! SOD - Start of data ! - ! EOC - End of code-stream ! - ! ! - ! DEVELOPMENT HISTORY: ! - ! -------------------- ! - ! ! - ! Date Author Change Id Release Description ! - ! ---- ------ --------- ------- ----------- ! - ! 01.12.2017 Patrick Vogler B87D120 V 0.1.0 macros created ! - ! ! - \*------------------------------------------------------------------------------------------------------------------*/ - #define SOC 0xFF50 - #define SGI 0xFF51 - #define SGC 0xFF52 - #define SAX 0xFF53 - #define TLM 0xFF54 - #define PLM 0xFF55 - #define PPM 0xFF56 - #define COM 0xFF57 - #define EOH 0xFF58 - #define PLT 0xFF60 - #define PPT 0xFF61 - #define SOT 0xFF90 - #define SOP 0xFF91 - #define EPH 0xFF92 - #define SOD 0xFF93 - #define EOC 0xFFFF - - /*------------------------------------------------------------------------------------------------------------------*\ - ! DESCRIPTION: ! - ! ------------ ! - ! ! - ! These macros define flags used for codestream parsing. ! - ! ! - ! MACROS: ! - ! ------- ! - ! Name Description ! - ! ---- ----------- ! - ! CODESTREAM_OK - No errors detected in Codestream ! - ! ! - ! CODESTREAM_READ - Codestream has been fully read. ! - ! ! - ! DEVELOPMENT HISTORY: ! - ! -------------------- ! - ! ! - ! Date Author Change Id Release Description ! - ! ---- ------ --------- ------- ----------- ! - ! 01.08.2019 Patrick Vogler B87D120 V 0.1.0 macros created ! - ! ! - \*------------------------------------------------------------------------------------------------------------------*/ - #define CODESTREAM_OK 0x00 - #define CODESTREAM_READ 0x80 - - /*------------------------------------------------------------------------------------------------------------------*\ - ! DESCRIPTION: ! - ! ------------ ! - ! ! - ! These Constants define common error messages used throughout the bwc library. ! - ! ! - ! MACROS: ! - ! ------- ! - ! Name Description ! - ! ---- ----------- ! - ! CSTERROR - Codestream parser has encoun- ! - ! tered invalid marker. ! - ! ! - ! MEMERROR - Allocation has returned a NULL ! - ! pointer due to limited memory. ! - ! ! - ! RDERROR - Invalid number of bytes read ! - ! from file. ! - ! ! - ! WRTERROR - Invalid number of bytes writ- ! - ! ten to file. ! - ! ! - ! DEVELOPMENT HISTORY: ! - ! -------------------- ! - ! ! - ! Date Author Change Id Release Description ! - ! ---- ------ --------- ------- ----------- ! - ! 01.12.2017 Patrick Vogler B87D120 V 0.1.0 macros created ! - ! ! - \*------------------------------------------------------------------------------------------------------------------*/ - #define CSTERROR "o##########################################################o\n"\ - "| ERROR: Invalid Codestream |\n"\ - "o##########################################################o\n" - - #define MEMERROR "o##########################################################o\n"\ - "| ERROR: Out of Memory |\n"\ - "o##########################################################o\n" - - #define RDERROR "o##########################################################o\n"\ - "| ERROR: Invalid Number of Bytes Read from File. |\n"\ - "o##########################################################o\n" - - #define WRTERROR "o##########################################################o\n"\ - "| ERROR: Invalid Number of Bytes Written to File. |\n"\ - "o##########################################################o\n" - - #define GET_DIM(x) (sizeof(x)/sizeof(*(x))) - /********************************************************************************************************************\ - || ___ ____ ____ ____ _ _ _ ____ ___ ___ _ _ ___ ____ ____ || - || | \ |___ |__/ |__/ | | | |___ | \ | \_/ |__] |___ [__ || - || |__/ |___ | \ | \ | \/ |___ |__/ | | | |___ ___] || - || || - \********************************************************************************************************************/ - /*------------------------------------------------------------------------------------------------------------------*\ - ! DESCRIPTION: ! - ! ------------ ! - ! ! - ! This structure defines the attributes of a single argument supported by the bwc ! - ! command line tool. ! - ! ! - ! PARAMETERS: ! - ! ----------- ! - ! Name Type Description ! - ! ---- ---- ----------- ! - ! active char - Flag indicating if the argu- ! - ! ment is active. ! - ! ! - ! arg_long char - Long form of the argument name. ! - ! ! - ! arg_short char - Short form of the argument ! - ! name. ! - ! ! - ! arg_type char - Flag signaling if the argument ! - ! is optional. ! - ! ! - ! type char - Flag signaling the argument ! - ! type. ! - ! ! - ! usage char - A string of 24 characters de- ! - ! scribing the argument usage. ! - ! ! - ! definition char - A string of 1024 characters ! - ! containing the argument de- ! - ! scription. ! - ! ! - ! DEVELOPMENT HISTORY: ! - ! -------------------- ! - ! ! - ! Date Author Change Id Release Description ! - ! ---- ------ --------- ------- ----------- ! - ! 14.02.2019 Patrick Vogler B87D120 V 0.1.0 struct created ! - ! 26.11.2020 Patrick Vogler B87E7E4 V 0.1.0 clean up ! - ! ! - \*------------------------------------------------------------------------------------------------------------------*/ - typedef struct - { - char active; - char arg_long[25]; - char arg_short[3]; - char arg_type[4]; - char type[5]; - char usage[25]; - char definition[1024]; - } bwc_cmdl_args; - - /*------------------------------------------------------------------------------------------------------------------*\ - ! DESCRIPTION: ! - ! ------------ ! - ! This structure describes a linked list which stores all the arguments and their ! - ! attributes supplied to the command line tool by the user. ! - ! ! - ! PARAMETERS: ! - ! ----------- ! - ! Name Type Description ! - ! ---- ---- ----------- ! - ! hash unsigned int(64 bit) - Uniquely identifiable hash that ! - ! corresponds to the arg/opt name. ! - ! ! - ! count unsigned int(8 bit) - Counter that signifies the num- ! - ! ber of modifier values stored ! - ! in the linked list node. ! - ! ! - ! dim unsigned int(8 bit) - Dimension(s) for which the mod- ! - ! ifiers have been defined ! - ! ! - ! active char - Flag indicating if the arg/opt ! - ! is active. ! - ! ! - ! num_opt double* - Array of numerical modifier ! - ! values. ! - ! ! - ! lit_opt char** - Character array of literal mod- ! - ! ifier values. ! - ! ! - ! DEPENDENCIES: ! - ! ------------- ! - ! Name TYPE ! - ! ---- ---- ! - ! next opt* ! - ! ! - ! root opt* ! - ! ! - ! DEVELOPMENT HISTORY: ! - ! -------------------- ! - ! ! - ! Date Author Change Id Release Description ! - ! ---- ------ --------- ------- ----------- ! - ! 26.04.2019 Patrick Vogler B87D120 V 0.1.0 struct created ! - ! 26.11.2020 Patrick Vogler B87E7E4 V 0.1.0 clean up ! - ! ! - \*------------------------------------------------------------------------------------------------------------------*/ - typedef struct arg - { - uint64_t hash; - uint8_t count; - uint8_t dim; - char active; - double *num_opt; - char **lit_opt; - struct arg *next; - struct arg *root; - } bwc_cmdl_arg_node; -#endif \ No newline at end of file diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index 8b29197..cbc5815 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -14,7 +14,7 @@ || || \* -------------------------------------------------------------------------------------------- */ /** - * @file test.c + * @file bwccmdl.c * * This file defines 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 @@ -48,13 +48,13 @@ #include #include #include +#include #include #include #include #include "eas3.h" #include "bwc.h" -#include "bwccmdl.h" /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*\ || _ _ ____ ____ ____ ____ ____ || @@ -63,6 +63,44 @@ || || \*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ /// @cond DO_NOT_DOCUMENT +/*================================================================================================*/ +/** + * @details These macros define common error messages used throughout the BigWhoop cli. + */ +/*================================================================================================*/ +#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" + +/*================================================================================================*/ +/** + * @details These macros are used to set and probe the cli_arguments optSet variable + */ +/*================================================================================================*/ +#define BITRT 0x8000 +#define CBLKS 0x4000 +#define CMPRT 0x2000 +#define DCLVL 0x1000 +#define DWTKL 0x0800 +#define FLOUT 0x0400 +#define FLREF 0x0200 +#define OMPTH 0x0100 +#define PRORD 0x0080 +#define PRECS 0x0040 +#define QFRMT 0x0020 +#define QTSIZ 0x0010 +#define QTSTL 0x0008 +#define TILES 0x0004 +#define USQLY 0x0002 + /*================================================================================================*/ /** * @details This macro defines a simple operation to remove a supplied deliminator from a string. @@ -81,6 +119,24 @@ || |___ |__| | \| ___] | | | | \| | ___] || || || \*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ +/*================================================================================================*/ +/** + * @details String containing the header used for the cli output. + */ +/*================================================================================================*/ +static char bwc_header[] = "==============================================================\n"\ + " \n"\ + " .:-------------: .:-------------: \n"\ + " .+++++++++++++++= :+++++++++++++++- \n"\ + " :+++. -++= -++= \n"\ + " :+++. -++= -++= \n"\ + " -++++++++++++++= -++= -++= \n"\ + " .=++---------=++= -++= -++= \n"\ + " :+++ :++= -++= -++= \n"\ + " .+++=--------=+++---=+++---=+++------------: \n"\ + " -=++++++++++++++++++++++++++++++++++++++++- \n"\ + " \n"; + /*================================================================================================*/ /** * @details Character strings containing the cli version and bug report e-mail address. @@ -101,10 +157,10 @@ static char doc[] = "\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"\ + " 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" @@ -117,13 +173,13 @@ static char doc[] = "\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"; + " 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"*/ + " sdir = * or sdir = x,y,z,ts.\n"*/ //=================================================================================================| /** @@ -138,21 +194,21 @@ static struct argp_option options[] = { //====================|=====|============|====================|================================|===| {0, 0, 0, 0, " [FILE OPTIONS]\n", 1}, //--------------------|-----|------------|--------------------|--------------------------------|---| -{"analysis", 'a', "", 0, "Analyze Peak Signal to Noise" +{"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}, +{"comp", 'C', "", 0, "Compress a numerical dataset.", 1}, //--------------------|-----|------------|--------------------|--------------------------------|---| -{"decomp", 'd', "", 0, "Decompress a BigWhoop file.", 1}, +{"decomp", 'D', "", 0, "Decompress a BigWhoop file.", 1}, //--------------------|-----|------------|--------------------|--------------------------------|---| -{"header", 'h', "", 0, "Display the header information" +{"header", 'H', "", 0, "Display the header information" " of a BigWhoop file.\n", 1}, //--------------------|-----|------------|--------------------|--------------------------------|---| -{"output", 'o', "", 0, "Defines output file.", 1}, +{"output", 'O', "", 0, "Defines output file.", 1}, //--------------------|-----|------------|--------------------|--------------------------------|---| -{"reference", 'r', "", 0, "Reference file used for PSNR" +{"reference", 'R', "", 0, "Reference file used for PSNR" " and MSE calculation.", 1}, //====================|=====|============|====================|================================|===| //--------------------|-----|------------|--------------------|--------------------------------|---| @@ -165,9 +221,6 @@ static struct argp_option options[] = { "for error resilient decoding 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}, @@ -184,13 +237,13 @@ static struct argp_option options[] = { "point. Accepts real numbers in " "the range of 0 < * < 64.\n", 3}, //--------------------|-----|------------|--------------------|--------------------------------|---| -{"codeblock", 'B', "", 0, "Codeblock size in log2 format. " +{"codeblock", 'c', "", 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 decomposi" +{"decomplvl", 'd', "", 0, "Number of wavelet decomposi" "tions applied to the data " "arrays. Accepts natural numbers" " in the range of 1 <= * <= 63." @@ -217,13 +270,13 @@ static struct argp_option options[] = { "Accepts real numbers in the " "range of 0 < * < 2.\n", 3}, //--------------------|-----|------------|--------------------|--------------------------------|---| -{"qformat", 'Q', "", 0, "Fractional bits of the Q number" +{"qformat", 'm', "", 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 uncom" +{"compratio", 'r', "", 0, "Target ratio between the uncom" "presssed and compressed file " "size. Accepts positive real " "numbers.\n", 3}, @@ -254,11 +307,11 @@ static struct argp_option options[] = { /*=====================================================|==========================================*/ typedef enum { - cli_err, //!< Command-line interface error + cli_ini, //!< Undefined command line mode cli_cmp, //!< Compression run cli_dcp, //!< Decompression run cli_anl, //!< Analyse distortion of reconstr. file - cli_hdr, //!< Display header information + cli_inf, //!< Display BWC Header Information } cli_mode; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*\ @@ -274,15 +327,33 @@ typedef enum /*===========================|=========================|==========================================*/ typedef struct { + char *args[2]; cli_mode mode; //!< Current state of the cli tool + uint16_t optSet; //!< Flag signaling witch opt has been set - FILE *fpIn, *fpOut; //!< Pointer to input/output file - char* *in, *out; //!< Name of the input/output files + char *in, *out, *ref; //!< Name of the in/out/ref file - float bitrate[10]; //!< Quality layers defined by bitrate. + bool erresilience; //!< Flag signalling error resilience + bool verbose; //!< Flag signalling verbose output - bwc_stream *stream; //!< Structure defining the BigWhoop I/O - bwc_codec *codec; //!< Structure defining the BigWhoop codec + uint64_t tileSize[4]; //!< Spatial/Temporal tile size + uint8_t precSize[4]; //!< Spatial/Temporal precinct size + uint8_t cblkSize[4]; //!< Spatial/Temporal codeblock size + + bwc_dwt_filter dwtKernel[4]; //!< Spatial/Temporal wavelet kernels + + double rate[10]; //!< Quality layers defining rate ctrl. + uint8_t decompLevel[4]; //!< N.o. Spatial/temporal dwt decompo. + + double qt_step_size; //!< Global qunatization step size + uint8_t Qm; //!< Q number format range (m) + + uint8_t useLayer; //!< Quality layer used for decompression + + uint64_t nThreads; //!< Number of OpenMP threads + + //bwc_quant_st quantization_style; //!< Quantization style + //bwc_prog_ord progression; //!< Packet progression order } cli_arguments; @@ -294,8 +365,48 @@ typedef struct \*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ /*================================================================================================*/ /** - * @details This function analyzes one option at a time and sets the corresponding value and - * passes arguments in the bwc_codec struct. + * @details This function takes the argument string, removes the supplied deliminators and + * verifies that the values are valid. If decimal is set to true the decimal point + * in a floating point value will be ignored. + * + * @param[in] arg Argument corresponding to the option key. + * @param[in] delim Character used to deliminate between values. + * @param[in] dec Bool signaling if string contains floating point values. + * + * @retval -1 Error + * @retval 0 OK + */ +/*================================================================================================*/ +static error_t +verify_opt(char *arg, char deliminator, bool decimal) +{ + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char *parse; + + remove_deliminator(arg, parse, deliminator); + + for(parse = arg; *parse; parse++) + { + if (decimal == true) + { + if (!isdigit(*parse) && *parse != ' ' && *parse != '.') + return EXIT_FAILURE; + } + else + { + if (!isdigit(*parse) && *parse != ' ') + return EXIT_FAILURE; + } + } + return EXIT_SUCCESS; +} + +/*================================================================================================*/ +/** + * @details This function analyzes one option at a time and sets the corresponding value in + * the cli arguments struct. * * @param[in] key Option's key corresponding to the field value in the arg_option struct. * @param[in] arg Argument corresponding to the option key. @@ -303,338 +414,646 @@ typedef struct * * @retval -1 Error * @retval 0 OK + */ +/*================================================================================================*/ 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; -/* + int64_t buff; uint8_t i; - //uint8_t length, shift; - */ /*-----------------------*\ ! DEFINE REAL VARIABLES: ! \*-----------------------*/ - /* + double compRatio; + double qt_step_size; float bitrate; - */ + /*-----------------------*\ - ! DEFINE REAL VARIABLES: ! + ! DEFINE CHAR VARIABLES: ! \*-----------------------*/ - /* char *end; - */ + char *token, *ptr; /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - /* cli_arguments *arguments; bwc_codec *codec; bwc_stream *stream; - */ /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - /* assert(state); - */ - /*--------------------------------------------------------*\ - ! Save frequently used variables/structures to temporary ! - ! variables to make the code more readable. ! - \*--------------------------------------------------------*/ - /* + /* Save frequently used variables/structures to * + * temporary variables. */ arguments = state->input; - codec = arguments->codec; - stream = arguments->stream; - */ - /*--------------------------------------------------------*\ - ! Parse the cli arguments according to the supplied opt. ! - \*--------------------------------------------------------*/ - /* + /* Parse the cli arguments. */ switch(key) { - case 'c': + /* Ingest compression argument. */ + case 'C': { - arguments->mode = bwc_cmp; - printf("Compress\n"); - if(arg[0] == '-') + if (arguments->mode != cli_ini) { - argp_error(state, "No input specified\n"); + argp_error(state, "Arguments define multiple use cases.\n"); + } + else if ((arg == NULL) || (arg[0] == '-')) + { + argp_error(state, "file names that start with an '-'" + " are not supported.\n"); } else { - arguments->input = ; + arguments->mode = cli_cmp; + arguments->in = arg; } break; } - case 'd': + + /* Ingest decompression argument. */ + case 'D': { - arguments->mode = bwc_dcp; - printf("Decompress\n"); + if (arguments->mode != cli_ini) + { + argp_error(state, "Arguments define multiple use cases.\n"); + } + else if ((arg == NULL) || (arg[0] == '-')) + { + argp_error(state, "file names that start with an '-'" + " are not supported.\n"); + } + else + { + arguments->mode = cli_dcp; + arguments->in = arg; + } break; } - case 'a': + + /* Ingest analysis argument. */ + case 'A': { - //arguments->analysis = arg; + if (arguments->mode != cli_ini) + { + argp_error(state, "Arguments define multiple use cases.\n"); + } + else if ((arg == NULL) || (arg[0] == '-')) + { + argp_error(state, "file names that start with an '-'" + " are not supported.\n"); + } + else + { + arguments->mode = cli_anl; + arguments->in = arg; + } + break; } - case 'h': + + /* Ingest header info argument. */ + case 'H': { - //arguments->header = arg; + if (arguments->mode != cli_ini) + { + argp_error(state, "Arguments define multiple use cases.\n"); + } + else if ((arg == NULL) || (arg[0] == '-')) + { + argp_error(state, "file names that start with an '-'" + " are not supported.\n"); + } + else + { + arguments->mode = cli_inf; + arguments->in = arg; + } + break; } - case 'o': + + /* Ingest output argument. */ + case 'O': { - //arguments->output = arg; + if (arguments->optSet & FLOUT) + { + argp_error(state, "The output file can only be defined once.\n"); + } + + if ((arg == NULL) || (arg[0] == '-')) + { + argp_error(state, "file names that start with an '-'" + " are not supported.\n"); + } + else + { + arguments->out = arg; + arguments->optSet |= FLOUT; + } break; } - case 'r': + + /* Ingest reference argument. */ + case 'R': { - //arguments->reference = arg; - break; - } - case 's': - { - //arguments->stream = 1; + if (arguments->optSet & FLREF) + { + argp_error(state, "The reference file can only be defined once.\n"); + } + + if ((arg == NULL) || (arg[0] == '-')) + { + argp_error(state, "file names that start with an '-'" + " are not supported.\n"); + } + else + { + arguments->ref = arg; + arguments->optSet |= FLREF; + } break; } + + /* Ingest verbose argument. */ case 'v': { - //arguments->stream = 1; + arguments->verbose = true; break; } + + /* Ingest bit rates. */ case 'b': { - remove_deliminator(arg, end, ','); + if (arguments->optSet & BITRT) + { + argp_error(state, "The bitrate can only be defined once.\n"); + } + else if (arguments->optSet & CMPRT) + { + argp_error(state, "The size reduction requires to be specified " + "either by a bit rate or a compression ratio, " + "never both.\n"); + } + + if (verify_opt(arg, ',', true) == EXIT_FAILURE) + { + argp_error(state, "Invalid delimitnator in the bitrate option\n"); + } for(bitrate = strtod(arg, &end), i = 0; arg != end && i < 10; bitrate = strtod(arg, &end), i++) { arg = end; - if(bitrate > 0 && bitrate < 64 && errno != ERANGE) + if (bitrate > 0 && bitrate <= 64 && errno != ERANGE) { - arguments->bitrate[i] = (float) bitrate; + arguments->rate[i] = (double) bitrate; } else { + errno = 0; argp_error(state, "The specified bitrate (%f) is " "out of the supported range.\n", bitrate); - - arguments->mode = cli_err; + } + } + + arguments->optSet |= BITRT; + break; + } + + /* Ingest codeblock size. */ + case 'c': + { + if (arguments->optSet & CBLKS) + { + argp_error(state, "The codeblock size can only be defined once.\n"); + } + + if (verify_opt(arg, ',', false) == EXIT_FAILURE) + { + argp_error(state, "Invalid delimitnator in the codeblock" + " size option.\n"); + } + + for(buff = strtoll(arg, &end, 10), i = 0; arg != end && i < 4; + buff = strtoll(arg, &end, 10), i++) + { + arg = end; + + if (buff >= 0 && buff <= 10 && errno != ERANGE) + { + arguments->cblkSize[i] = (uint8_t) buff; + } + else + { errno = 0; + argp_error(state, "The specified codeblock size (%ld) " + "is out of the supported range.\n", buff); break; } } - break; - } - 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++) + if (i == 1) { - 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); - } + arguments->cblkSize[1] = + arguments->cblkSize[2] = + arguments->cblkSize[3] = arguments->cblkSize[0]; } - - if(i == 1) - { - arguments->codeblock[1] = - arguments->codeblock[2] = - arguments->codeblock[3] = arguments->codeblock[0]; - } - else if(i != 4) + else if (i != 4) { argp_error(state, "The codeblock argument expects either a " "single global or 4 directional values\n"); - }*/ - /* + } + + arguments->optSet |= CBLKS; break; } + + /* Ingest compression ratio. */ + case 'r': + { + if (arguments->optSet & CMPRT) + { + argp_error(state, "The compression ratio can only be defined once.\n"); + } + else if (arguments->optSet & BITRT) + { + argp_error(state, "The size reduction requires to be specified " + "either by a bit rate or a compression ratio, " + "never both.\n"); + } + + if (verify_opt(arg, ',', true) == EXIT_FAILURE) + { + argp_error(state, "Invalid delimitnator in the compression" + " ratio option \n"); + } + + for(compRatio = strtod(arg, &end), i = 0; arg != end && i < 10; + compRatio = strtod(arg, &end), i++) + { + arg = end; + + if (compRatio > 0 && compRatio < 65536 && errno != ERANGE) + { + arguments->rate[i] = (double) compRatio; + } + else + { + errno = 0; + argp_error(state, "The specified bitrate (%d) is " + "out of the supported range.\n", compRatio); + } + } + + arguments->optSet |= CMPRT; + break; + } + + /* Ingest decomposition level. */ + case 'd': + { + if (arguments->optSet & DCLVL) + { + argp_error(state, "The compression ratio can only be defined once.\n"); + } + + if (verify_opt(arg, ',', false) == EXIT_FAILURE) + { + argp_error(state, "Invalid delimitnator in the decomposition" + " level option.\n"); + } + + for(buff = strtoll(arg, &end, 10), i = 0; arg != end && i < 4; + buff = strtoll(arg, &end, 10), i++) + { + arg = end; + + if (buff > 0 && buff <= 63 && errno != ERANGE) + { + arguments->decompLevel[i] = (uint8_t) buff; + } + else + { + errno = 0; + argp_error(state, "The specified decomposition level (%ld) " + "is out of the supported range.\n", buff); + break; + } + } + + if (i == 1) + { + arguments->decompLevel[1] = + arguments->decompLevel[2] = + arguments->decompLevel[3] = arguments->decompLevel[0]; + } + else if (i != 4) + { + argp_error(state, "The decomposition level argument expects either a " + "single global or 4 directional values\n"); + } + + arguments->optSet |= DCLVL; + break; + } + + /* Ingest number of OpenMP threads. */ 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; - // } + if (arguments->optSet & OMPTH) + { + argp_error(state, "The number of OpenMP threads can only be " + "defined once.\n"); + } + + buff = strtoll(arg, &end, 10); + + if (errno == ERANGE) + { + errno = 0; + argp_error(state, "The specified number of OpenMP threads (%ld) " + "is out of the supported range.\n", buff); + } + else + { + arguments->nThreads = (uint64_t) buff; + } + + arguments->optSet |= OMPTH; break; } + + /* Ingest quality layer to be used for decompression. */ case 'l': { - printf("l\n"); + if (arguments->optSet & USQLY) + { + argp_error(state, "The quality layer used for decompression" + " can only be defined once.\n"); + } + + buff = strtoll(arg, &end, 10); + + if (buff > 0 && buff <= 255 && errno != ERANGE) + { + errno = 0; + argp_error(state, "The specified quality layer (%ld) " + "is out of the supported range.\n", buff); + } + else + { + arguments->useLayer = (uint8_t) buff; + } + + arguments->optSet |= USQLY; break; } + + /* Ingest wavelet kernels. */ case 'k': { - printf("k\n"); + if (arguments->optSet & DWTKL) + { + argp_error(state, "The wavelet kernels can only be defined once.\n"); + } + + for(token = strtok_r(arg, ",", &ptr), i = 0; + token != NULL, i < 4; + token = strtok_r(NULL, ",", &ptr), i++) + { + if (strcasecmp(token, "leGall") == 0) + arguments->dwtKernel[i] = bwc_dwt_5_3; + else if (strcasecmp(token, "CDF") == 0) + arguments->dwtKernel[i] = bwc_dwt_9_7; + else if (strcasecmp(token, "Haar") == 0) + arguments->dwtKernel[i] = bwc_dwt_haar; + else + argp_error(state, "Waveket kernel %s is unknown " + "to the library.\n", token); + } + + if (i == 1) + { + arguments->dwtKernel[1] = + arguments->dwtKernel[2] = + arguments->dwtKernel[3] = arguments->dwtKernel[0]; + } + else if (i != 4) + { + argp_error(state, "The wavelet kernel argument expects either a " + "single global or 4 directional values\n"); + } + + arguments->optSet |= DWTKL; break; } + + /* Ingest quantization step size. */ case 'q': { - printf("q\n"); + if (arguments->optSet & QTSIZ) + { + argp_error(state, "The quantization step size can only be " + "defined once.\n"); + } + + qt_step_size = strtod(arg, &end); + + if (qt_step_size > 0 && qt_step_size < 2 && errno != ERANGE) + { + arguments->qt_step_size = (double) qt_step_size; + } + else + { + errno = 0; + argp_error(state, "The specified quantization step size (%f) is " + "out of the supported range.\n", qt_step_size); + } + + arguments->optSet |= QTSIZ; break; } - case 'Q': + + /* Ingest Q number format range. */ + case 'm': { - printf("Q\n"); + if (arguments->optSet & QFRMT) + { + argp_error(state, "The Q format range can only be defined once.\n"); + } + + buff = strtoll(arg, &end, 10); + if (buff > 0 && buff < 63 && errno != ERANGE) + { + arguments->Qm = (uint8_t) buff; + } + else + { + errno = 0; + argp_error(state, "The specified Q number format range (%ld) " + "is out of the supported range.\n", buff); + } + + arguments->optSet |= QFRMT; break; } + + /* Ingest error resilience setting. */ case 'e': { - printf("e\n"); + arguments->erresilience = true; break; } + + /* Ingest tile size. */ case 't': { - printf("t\n"); + if (arguments->optSet & TILES) + { + argp_error(state, "The tile size can only be defined once.\n"); + } + + if (verify_opt(arg, ',', false) == EXIT_FAILURE) + { + argp_error(state, "Invalid delimitnator in the tile" + " size option.\n"); + } + + for(buff = strtoll(arg, &end, 10), i = 0; arg != end && i < 4; + buff = strtoll(arg, &end, 10), i++) + { + arg = end; + + if (buff >= 16 && errno != ERANGE) + { + arguments->tileSize[i] = (uint64_t) buff; + } + else + { + errno = 0; + argp_error(state, "The specified tile size (%ld) " + "is out of the supported range.\n", buff); + break; + } + } + + if (i == 1) + { + arguments->tileSize[1] = + arguments->tileSize[2] = + arguments->tileSize[3] = arguments->tileSize[0]; + } + else if (i != 4) + { + argp_error(state, "The tile argument expects either a " + "single global or 4 directional values\n"); + } + + arguments->optSet |= TILES; break; } + + /* Ingest precinct size. */ case 'p': { - printf("p\n"); + if (arguments->optSet & PRECS) + { + argp_error(state, "The precinct size can only be defined once.\n"); + } + + if (verify_opt(arg, ',', false) == EXIT_FAILURE) + { + argp_error(state, "Invalid delimitnator in the precinct" + " size option.\n"); + } + + for(buff = strtoll(arg, &end, 10), i = 0; arg != end && i < 4; + buff = strtoll(arg, &end, 10), i++) + { + arg = end; + + if (buff >= 0 && buff <= 15 && errno != ERANGE) + { + arguments->precSize[i] = (uint8_t) buff; + } + else + { + errno = 0; + argp_error(state, "The specified precinct size (%ld) " + "is out of the supported range.\n", buff); + break; + } + } + + if (i == 1) + { + arguments->precSize[1] = + arguments->precSize[2] = + arguments->precSize[3] = arguments->precSize[0]; + } + else if (i != 4) + { + argp_error(state, "The precinct argument expects either a " + "single global or 4 directional values\n"); + } + + arguments->optSet |= PRECS; break; } - case ARGP_KEY_NO_ARGS: - { - argp_usage (state); - break; - } - - case ARGP_KEY_ARG: - - // Too many arguments. - if(state->arg_num > 1) - argp_usage(state); - break; - + /* Check if the user supplied options fit the supported * + * use case. */ 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))) + { + if (((arguments->mode == cli_cmp || + arguments->mode == cli_dcp) && (arguments->in == NULL || arguments->ref != NULL)) || + (arguments->mode == cli_inf && (arguments->in == NULL || arguments->ref != NULL + || arguments->out != NULL)) || + (arguments->mode == cli_anl && (arguments->in == NULL || arguments->ref == NULL + || arguments->out != NULL))) { argp_error(state, "The User supplied options do not fit the " "supported use cases.\n"); - }*/ - /* + } + else if (arguments->mode == cli_ini) + { + argp_usage(state); + } break; + } + /* Output standard usage message if no arg is defined. */ + case ARGP_KEY_NO_ARGS: + { + if (arguments->mode == cli_ini) + argp_usage (state); + } + + /* Return error if key is unknown. */ default: - return ARGP_ERR_UNKNOWN; + 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}; +/*================================================================================================*/ +/** + * @details Initialize the argp struct. used to parse the command line arguments + */ +/*================================================================================================*/ +static struct argp argp = {options, parse_opt, 0, doc}; /*================================================================================================*/ /** @@ -650,97 +1069,193 @@ parse_opt(int key, /*================================================================================================*/ int main(int argc, char *argv[]) { - int i = 0; - int size = 0; + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64_t size = 0; + uint8_t i; + uint8_t error_handle; + + + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + double rtype; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char rate[200] = {0}; + + unsigned char *input; + unsigned char *output; + + /*-----------------------*\ + ! DEFINE DER. VARIABLES: ! + \*-----------------------*/ + bwc_precision precision; + bwc_stream *stream; + bwc_codec *coder; + /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - cli_arguments arguments = {0}; + eas3_data *data; + cli_arguments arguments = {0}; - eas3_data *data; - uchar *input; - uchar *output; + /* Parse the command line arguments and invoke the appro- * + * priate bwccmdl mode. */ + if (argp_parse(&argp, argc, argv, 0, 0, &arguments) == EXIT_FAILURE) + { + error_handle = EXIT_FAILURE; + goto OUT; + } - data = read_eas3("TGV_125.eas"); + /* Compress the user supplied data set. */ + if (arguments.mode == cli_cmp) + { + // TODO: Define a universal data structure and implement a reader + // that ingests different file formats + if ((data = read_eas3(arguments.in)) == NULL) + { + error_handle = EXIT_FAILURE; + goto OUT; + } - printf("I read eas3. No guarantees. Check validity. Compression will start now ...\n"); - - size = data->params.ndim1 * data->params.ndim2 * - data->params.ndim3 * data->params.nts * - data->params.npar; + /* Evaluate the input and output buffer size and initial- * + * ize the BigWhoop data and coder structs. */ + size = data->params.ndim1 * data->params.ndim2 * + data->params.ndim3 * data->params.nts * + data->params.npar; - bwc_precision precision; - if (data->params.accuracy == 1) - { - precision = bwc_precision_single; - input = (uchar*)data->field.f; - output = calloc(size, sizeof(float)); - } - else if (data->params.accuracy == 2) - { - precision = bwc_precision_double; - input = (uchar*)data->field.d; - output = calloc(size, sizeof(double)); - } + if (data->params.accuracy == 1) + { + precision = bwc_precision_single; + input = (unsigned char*)data->field.f; + output = calloc(size, sizeof(float)); + } + else if (data->params.accuracy == 2) + { + precision = bwc_precision_double; + input = (unsigned char*)data->field.d; + output = calloc(size, sizeof(double)); + } - bwc_mode mode = comp; - bwc_stream* stream = bwc_init_stream(input, output, comp); - bwc_codec* coder = bwc_alloc_coder(data->params.ndim1, - data->params.ndim2, - data->params.ndim3, - data->params.nts, - data->params.npar, - precision); - // TODO: implement setters for codeblocks, decomposition etc. - //bwc_set_qm(coder, 32); - char rate[10]; // TODO: replace with cmdl argument - sprintf(rate, "%05.3f", 4.0); - rate[strlen(rate)-1] = '0'; - printf("rate %s \n", rate); + stream = bwc_init_stream(input, output, comp); + coder = bwc_alloc_coder(data->params.ndim1, + data->params.ndim2, + data->params.ndim3, + data->params.nts, + data->params.npar, + precision); - bwc_create_compression(coder, stream, rate); - bwc_compress(coder, stream); - bwc_free_codec(coder); + /* Apply the user supplied compression options using the * + * appropriate setter functions. */ + if((arguments.optSet & QFRMT) != 0) + bwc_set_qm(coder, arguments.Qm); - // TODO: implement I/O of bwc file - // TODO: bwc_header_info + /*if((arguments.optSet & DWTKL) != 0) + { + bwc_set_kernels(coder, arguments.dwtKernel[0], + arguments.dwtKernel[1], + arguments.dwtKernel[2], + arguments.dwtKernel[3]); + }*/ - write_eas3(data, "output.eas"); - data = read_eas3("output.eas"); - write_eas3(data, "output2.eas"); + if((arguments.optSet & DCLVL) != 0) + { + bwc_set_decomp(coder, arguments.decompLevel[0], + arguments.decompLevel[1], + arguments.decompLevel[2], + arguments.decompLevel[3]); + } - eas3_free_data(data); - free(output); - - /*--------------------------------------------------------*\ - ! Initialize the arguments structure. ! - \*--------------------------------------------------------*/ - //arguments.stream = calloc(1, sizeof(bwc_stream)); - //arguments.codec = calloc(1, sizeof(bwc_codec)); - //if((arguments.stream == NULL) || - //(arguments.codec == NULL)) - //{ - // memory allocation error - //fprintf(stderr, MEMERROR); - //return EXIT_FAILURE; - //} + if((arguments.optSet & TILES) != 0) + { + bwc_set_tiles(coder, arguments.tileSize[0], + arguments.tileSize[1], + arguments.tileSize[2], + arguments.tileSize[3], bwc_tile_sizeof); + } - /*--------------------------------------------------------*\ - ! Parse the cli arguments. ! - \*--------------------------------------------------------*/ - //argp_parse(&argp, argc, argv, 0, 0, &arguments); - //if(arguments.mode == cli_err) - //{ - //return EXIT_FAILURE; - //} + if((arguments.optSet & PRECS) != 0) + { + bwc_set_precincts(coder, arguments.precSize[0], + arguments.precSize[1], + arguments.precSize[2], + arguments.precSize[3]); + } - //for(i = 0; i < 10; ++i) - //printf("bitrate %d:\t%f\n",i,arguments.bitrate[i]); + if((arguments.optSet & CBLKS) != 0) + { + bwc_set_codeblocks(coder, arguments.cblkSize[0], + arguments.cblkSize[1], + arguments.cblkSize[2], + arguments.cblkSize[3]); + } + /* Initialize the rate control string according to the * + * specified bit rate/compression ratio. */ + if((arguments.optSet & BITRT) != 0) + { + rtype = 1.0; + } + else if((arguments.optSet & CMPRT) != 0) + { + rtype = 64.0; + } + else + { + rtype = 1.0; + arguments.rate[0] = 64; + } + for(i = 0; i < 10 && strlen(rate) < 192; ++i) + { + if(arguments.rate[i] > 0) + sprintf(rate + strlen(rate), "%05.3f,", arguments.rate[i]/rtype); + } + rate[strlen(rate) - 1] = '0'; - //printf("ARG1: %s", arguments.args[0]); - //printf("\nVERBOSE: %s", arguments.verbose? "yes" : "no"); - //printf("\nOption1: %s", arguments.option1); - //printf("\n"); + /* Initialize the rate control string according to the * + * specified bit rate/compression ratio. */ + if (bwc_create_compression(coder, stream, rate) == EXIT_FAILURE) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + + bwc_compress(coder, stream); + } + else if (arguments.mode == cli_dcp) + { + printf("Decompression\n"); + } + else if (arguments.mode == cli_anl) + { + printf("Analysis\n"); + } + else if (arguments.mode == cli_inf) + { + printf("Header Info\n"); + } + else + { + return EXIT_FAILURE; + } + +OUT: + if (coder != NULL) + bwc_free_codec(coder); + + if (data != NULL) + eas3_free_data(data); + + if (stream !=NULL) + free(stream); + + if (output != NULL) + free(output); + + return error_handle; } -- 2.45.2 From d9799506264244fba818ef57600bd466c464240e Mon Sep 17 00:00:00 2001 From: Patrick Vogler Date: Tue, 29 Oct 2024 19:01:33 +0100 Subject: [PATCH 03/21] Implemented the compression path with verbose output and support for all options available to the user. --- src/tools/bwccmdl.c | 266 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 240 insertions(+), 26 deletions(-) diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index cbc5815..4a5ee0d 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -48,6 +48,8 @@ #include #include #include +#include +#include #include #include #include @@ -72,12 +74,20 @@ "| ERROR: Out of memory |\n"\ "o##########################################################o\n" +#define TYPERROR "o##########################################################o\n"\ + "| ERROR: Invalid file type. |\n"\ + "o##########################################################o\n" + +#define FOUERROR "o##########################################################o\n"\ + "| ERROR: Could not open specified output file. |\n"\ + "o##########################################################o\n" + #define RDERROR "o##########################################################o\n"\ - "| ERROR: Invalid Number of Bytes Read from File. |\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"\ + "| ERROR: Invalid number of bytes written to file. |\n"\ "o##########################################################o\n" /*================================================================================================*/ @@ -427,7 +437,6 @@ parse_opt(int key, int64_t buff; uint8_t i; - /*-----------------------*\ ! DEFINE REAL VARIABLES: ! \*-----------------------*/ @@ -435,7 +444,6 @@ parse_opt(int key, double qt_step_size; float bitrate; - /*-----------------------*\ ! DEFINE CHAR VARIABLES: ! \*-----------------------*/ @@ -1069,6 +1077,11 @@ static struct argp argp = {options, parse_opt, 0, doc}; /*================================================================================================*/ int main(int argc, char *argv[]) { + /*-----------------------*\ + ! DEFINE BOOL VARIABLES: ! + \*-----------------------*/ + bool delim = false; + /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ @@ -1076,20 +1089,29 @@ int main(int argc, char *argv[]) uint8_t i; uint8_t error_handle; - /*-----------------------*\ ! DEFINE REAL VARIABLES: ! \*-----------------------*/ - double rtype; + double rtype, exp; /*-----------------------*\ ! DEFINE CHAR VARIABLES: ! \*-----------------------*/ char rate[200] = {0}; + char cli_buffer[1024] = {0}; + char cli_verbose[4096] = {0}; + + char *cli_output; + char *buffer; unsigned char *input; unsigned char *output; + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp; + /*-----------------------*\ ! DEFINE DER. VARIABLES: ! \*-----------------------*/ @@ -1111,9 +1133,18 @@ int main(int argc, char *argv[]) goto OUT; } + /* Set the number of OpenMP threads. */ + #if defined (_OPENMP) + if (arguments.optSet & OMPTH) + omp_set_num_threads((int)arguments.nThreads); + #endif + /* Compress the user supplied data set. */ if (arguments.mode == cli_cmp) { + + /* Ingest the bwccmdl input and set the appropriate cli_ * + * verbose message if the option is set. */ // TODO: Define a universal data structure and implement a reader // that ingests different file formats if ((data = read_eas3(arguments.in)) == NULL) @@ -1121,11 +1152,47 @@ int main(int argc, char *argv[]) error_handle = EXIT_FAILURE; goto OUT; } + if (arguments.verbose == true) + { + strcat(cli_verbose, bwc_header); + strcat(cli_verbose, "--------------------------- I/O --------------------------\n\n"); + + sprintf(cli_buffer," Input: %s \n", arguments.in); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + } + + /* Evaluate the appropriate output file. */ + if ((arguments.optSet & FLOUT) == 0) + arguments.out = arguments.in; + + printf("%s \n", arguments.out); + if ((buffer = strrchr(arguments.out, '.')) == NULL) + { + error_handle = EXIT_FAILURE; + printf(TYPERROR); + goto OUT; + } + cli_output = calloc(strlen(arguments.out) - strlen(buffer) + 1, sizeof(char)); + if (cli_output == NULL) + { + error_handle = EXIT_FAILURE; + printf(MEMERROR); + goto OUT; + } + sprintf(cli_output, "%.*s.bwc", (int)(strlen(arguments.out) - strlen(buffer)), arguments.out); + + if (arguments.verbose == true) + { + sprintf(cli_buffer," Output: %s \n", cli_output); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + } /* Evaluate the input and output buffer size and initial- * * ize the BigWhoop data and coder structs. */ size = data->params.ndim1 * data->params.ndim2 * - data->params.ndim3 * data->params.nts * + data->params.ndim3 * data->params.nts * data->params.npar; if (data->params.accuracy == 1) @@ -1151,10 +1218,39 @@ int main(int argc, char *argv[]) /* Apply the user supplied compression options using the * * appropriate setter functions. */ - if((arguments.optSet & QFRMT) != 0) - bwc_set_qm(coder, arguments.Qm); + if (arguments.verbose == true) + { + strcat(cli_verbose, "\n"); + strcat(cli_verbose, "----------------- Compression Parameters -----------------\n"); + strcat(cli_verbose, "\n"); + } - /*if((arguments.optSet & DWTKL) != 0) + if ((arguments.optSet & TILES) != 0) + { + bwc_set_tiles(coder, arguments.tileSize[0], + arguments.tileSize[1], + arguments.tileSize[2], + arguments.tileSize[3], bwc_tile_sizeof); + + if (arguments.verbose == true) + { + strcat(cli_verbose," Tile Size: \n"); + sprintf(cli_buffer," - Samples in 1.D: %27ld\n"\ + " - Samples in 2.D: %27ld\n"\ + " - Samples in 3.D: %27ld\n"\ + " - Samples in 4.D: %27ld\n", arguments.tileSize[0], + arguments.tileSize[1], + arguments.tileSize[2], + arguments.tileSize[3]); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + delim = true; + } + } + + // TODO: Implement the kernel setter as a global function + // and define the proper verbose output layout. + /*if ((arguments.optSet & DWTKL) != 0) { bwc_set_kernels(coder, arguments.dwtKernel[0], arguments.dwtKernel[1], @@ -1162,61 +1258,160 @@ int main(int argc, char *argv[]) arguments.dwtKernel[3]); }*/ - if((arguments.optSet & DCLVL) != 0) + if ((arguments.verbose == true) && + ((arguments.optSet & (DCLVL | PRECS | CBLKS)) != 0)) + { + if (delim == true) + { + strcat(cli_verbose, " __________________________________________________________\n"); + strcat(cli_verbose, "\n"); + } + strcat(cli_verbose, " 1.D | 2.D | 3.D | 4.D\n"); + delim = true; + } + + if ((arguments.optSet & DCLVL) != 0) { bwc_set_decomp(coder, arguments.decompLevel[0], arguments.decompLevel[1], arguments.decompLevel[2], arguments.decompLevel[3]); + + if (arguments.verbose == true) + { + sprintf(cli_buffer, " Decomposition Levels: %18d |%4d |%4d |%4d\n", + arguments.decompLevel[0], + arguments.decompLevel[1], + arguments.decompLevel[2], + arguments.decompLevel[3]); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + } } - if((arguments.optSet & TILES) != 0) - { - bwc_set_tiles(coder, arguments.tileSize[0], - arguments.tileSize[1], - arguments.tileSize[2], - arguments.tileSize[3], bwc_tile_sizeof); - } - - if((arguments.optSet & PRECS) != 0) + if ((arguments.optSet & PRECS) != 0) { bwc_set_precincts(coder, arguments.precSize[0], arguments.precSize[1], arguments.precSize[2], arguments.precSize[3]); + + if (arguments.verbose == true) + { + sprintf(cli_buffer, " Precincts [log2]: %18d |%4d |%4d |%4d\n", + arguments.precSize[0], + arguments.precSize[1], + arguments.precSize[2], + arguments.precSize[3]); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + } } - if((arguments.optSet & CBLKS) != 0) + if ((arguments.optSet & CBLKS) != 0) { bwc_set_codeblocks(coder, arguments.cblkSize[0], arguments.cblkSize[1], arguments.cblkSize[2], arguments.cblkSize[3]); + + if (arguments.verbose == true) + { + sprintf(cli_buffer, " Codeblocks [log2]: %18d |%4d |%4d |%4d\n", + arguments.cblkSize[0], + arguments.cblkSize[1], + arguments.cblkSize[2], + arguments.cblkSize[3]); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + } + } + + if ((arguments.verbose == true) && + (delim == true) && + (((arguments.optSet & QFRMT) != 0) || arguments.erresilience == true)) + { + + strcat(cli_verbose, " __________________________________________________________\n"); + strcat(cli_verbose, "\n"); + } + + if ((arguments.optSet & QFRMT) != 0) + { + bwc_set_qm(coder, arguments.Qm); + + if (arguments.verbose == true) + { + sprintf(cli_buffer, " Q Number Format: %27d\n", arguments.Qm); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + delim = true; + } + } + + if (arguments.erresilience == true) + { + bwc_set_error_resilience(coder); + + if (arguments.verbose == true) + { + sprintf(cli_buffer, " Error Resilience: %27s\n", "true"); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + delim = true; + } } /* Initialize the rate control string according to the * * specified bit rate/compression ratio. */ - if((arguments.optSet & BITRT) != 0) + if ((arguments.verbose == true) && + (delim == true)) + { + + strcat(cli_verbose, " __________________________________________________________\n"); + strcat(cli_verbose, "\n"); + } + + if ((arguments.optSet & BITRT) != 0) { rtype = 1.0; + exp = 1.0; } - else if((arguments.optSet & CMPRT) != 0) + else if ((arguments.optSet & CMPRT) != 0) { rtype = 64.0; + exp = -1.0; } else { rtype = 1.0; + exp = 1.0; arguments.rate[0] = 64; } for(i = 0; i < 10 && strlen(rate) < 192; ++i) { - if(arguments.rate[i] > 0) - sprintf(rate + strlen(rate), "%05.3f,", arguments.rate[i]/rtype); + if (arguments.rate[i] > 0) + { + sprintf(rate + strlen(rate), "%05.3f,", pow(arguments.rate[i]/rtype, exp)); + + if (arguments.verbose == true) + { + sprintf(cli_buffer, " Quality Layer Nr. %d: %33.2f bpd\n", i, + pow(arguments.rate[i]/rtype, exp)); + strcat(cli_verbose, cli_buffer); + } + } } rate[strlen(rate) - 1] = '0'; + if (arguments.verbose == true) + { + memset(cli_buffer, '0', sizeof(char) * 1024); + strcat(cli_verbose, "\n==============================================================\n"); + printf("%s", cli_verbose); + } + /* Initialize the rate control string according to the * * specified bit rate/compression ratio. */ if (bwc_create_compression(coder, stream, rate) == EXIT_FAILURE) @@ -1225,7 +1420,23 @@ int main(int argc, char *argv[]) goto OUT; } - bwc_compress(coder, stream); + size = bwc_compress(coder, stream); + + /* Write the codestream to the speicifed file. */ + fp = fopen(cli_output, "wb"); + if (fp == NULL) + { + error_handle = EXIT_FAILURE; + printf(FOUERROR); + goto OUT; + } + + if (fwrite(stream->out, sizeof(uchar), size, fp) != size) + { + error_handle = EXIT_FAILURE; + printf(WRTERROR); + goto OUT; + } } else if (arguments.mode == cli_dcp) { @@ -1257,5 +1468,8 @@ OUT: if (output != NULL) free(output); + if (cli_output != NULL) + free(cli_output); + return error_handle; } -- 2.45.2 From 6716a2b1d47b49be3b214b3ec88fdb3f6e2fe03c Mon Sep 17 00:00:00 2001 From: Patrick Vogler Date: Tue, 29 Oct 2024 19:03:11 +0100 Subject: [PATCH 04/21] Updated the WARNING messages to fit the layout of the verbose command line tool output. --- src/library/libbwc.c | 159 ++++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 84 deletions(-) diff --git a/src/library/libbwc.c b/src/library/libbwc.c index bf01f88..d6ede6f 100755 --- a/src/library/libbwc.c +++ b/src/library/libbwc.c @@ -2490,15 +2490,14 @@ set_quant_step_size(bwc_codec *const codec, double delta) \*--------------------------------------------------------*/ 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"); + fprintf(stderr, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\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"); return; } @@ -2782,14 +2781,13 @@ bwc_set_decomp(bwc_codec *const codec, uint8 decompX, uint8 decompY, uint8 decom 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"); + fprintf(stderr, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\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"); /*--------------------------------------------------------*\ ! Reset the decomposition levels to their standard values. ! @@ -2924,13 +2922,12 @@ bwc_set_precincts(bwc_codec *const codec, uint8 pX, uint8 pY, uint8 pZ, uint8 pT ((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"); + fprintf(stderr, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\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"); /*--------------------------------------------------------*\ ! Reset the codeblock sizes to their standard values. ! @@ -3023,15 +3020,14 @@ bwc_set_codeblocks(bwc_codec *const codec, uint8 cbX, uint8 cbY, uint8 cbZ, uint ((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"); + fprintf(stderr, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\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"); /*--------------------------------------------------------*\ ! Reset the codeblock sizes to their standard values. ! @@ -3106,19 +3102,18 @@ bwc_set_qm(bwc_codec *const codec, uint8 Qm) ! Check if the Q number formate range is valid and amend ! ! the bwc_codec structure accordingly. ! \*--------------------------------------------------------*/ - if((int8)(PREC_BIT - Qm) < 2) + if((int8)(PREC_BIT - Qm) < 1) { - fprintf(stderr, "o==========================================================o\n"\ - "| WARNING: Invalid Q number formate range |\n"\ - "| |\n"\ - "| The specified Q number formate range is larger |\n"); + fprintf(stderr, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\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"); + fprintf(stderr, " than the permitted 30 bits. \n"); #else - fprintf(stderr, "| than the permitted 62 bits. |\n"); + fprintf(stderr, " than the permitted 62 bits. \n"); #endif - fprintf(stderr, "| |\n"\ - "o==========================================================o\n"); + fprintf(stderr, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } else { @@ -3213,17 +3208,16 @@ bwc_set_tiles(bwc_codec *const codec, uint64 tilesX, uint64 tilesY, uint64 tiles (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"); + fprintf(stderr,">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\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"); return; } @@ -3255,16 +3249,15 @@ bwc_set_tiles(bwc_codec *const codec, uint64 tilesX, uint64 tilesY, uint64 tiles \*--------------------------------------------------------*/ 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"); + fprintf(stderr,">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\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"); /*--------------------------------------------------------*\ ! Reset the tile sizes to their standard values. ! @@ -3285,15 +3278,14 @@ bwc_set_tiles(bwc_codec *const codec, uint64 tilesX, uint64 tilesY, uint64 tiles \*--------------------------------------------------------*/ 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"); + fprintf(stderr,">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\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"); return; } @@ -3318,18 +3310,17 @@ bwc_set_tiles(bwc_codec *const codec, uint64 tilesX, uint64 tilesY, uint64 tiles (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"); + fprintf(stderr,">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\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"); /*--------------------------------------------------------*\ ! Reset the tile sizes to their standard values. ! -- 2.45.2 From f81807e1e35b269f26d03e7b5cd91a67045f5a14 Mon Sep 17 00:00:00 2001 From: Patrick Vogler Date: Wed, 30 Oct 2024 12:38:56 +0100 Subject: [PATCH 05/21] Fixed some memory leak issues. --- src/interfaces/reader/eas3.c | 41 +++++++++++++++++++++++------------- src/tools/bwccmdl.c | 32 +++++++++++++++------------- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/interfaces/reader/eas3.c b/src/interfaces/reader/eas3.c index 7581118..b5a3554 100644 --- a/src/interfaces/reader/eas3.c +++ b/src/interfaces/reader/eas3.c @@ -231,22 +231,36 @@ endian_conversion(void *value, void eas3_free_data(eas3_data* data) { - if(data != NULL) - { - if (data->param_names != NULL) - free(data->param_names); + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + eas3_param_names *param, *temp; + + if(data != NULL) + { + if (data->param_names != NULL) + { + param = data->param_names->root; + + while(param != NULL) + { + temp = param; + param = param -> next; + free(temp); + } + } - if (data->field.d != NULL) - free(data->field.d); + if (data->field.d != NULL) + free(data->field.d); - if (data->field.f != NULL) - free(data->field.f); + if (data->field.f != NULL) + free(data->field.f); - if(data->aux.ptr != NULL) - free(data->aux.ptr); + if(data->aux.ptr != NULL) + free(data->aux.ptr); - free(data); - } + free(data); + } } void @@ -345,7 +359,6 @@ read_eas3_header(FILE *const fp, eas3_data *const data) \*-----------------------*/ uint64 Lread; uint64 i; - uint8 precision; /*-----------------------*\ ! DEFINE CHAR VARIABLES: ! @@ -356,7 +369,6 @@ read_eas3_header(FILE *const fp, eas3_data *const data) /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - bwc_gl_inf *info; eas3_std_params *params; /*-----------------------*\ @@ -702,7 +714,6 @@ write_eas3_header(FILE *const fp, eas3_data *const data) /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - bwc_gl_inf *info; eas3_std_params *params; eas3_param_names *param_names; diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index 4a5ee0d..db9f10e 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -454,8 +454,6 @@ parse_opt(int key, ! DEFINE STRUCTS: ! \*-----------------------*/ cli_arguments *arguments; - bwc_codec *codec; - bwc_stream *stream; /*-----------------------*\ ! DEFINE ASSERTIONS: ! @@ -720,7 +718,7 @@ parse_opt(int key, else { errno = 0; - argp_error(state, "The specified bitrate (%d) is " + argp_error(state, "The specified compression ratio (%f) is " "out of the supported range.\n", compRatio); } } @@ -838,7 +836,7 @@ parse_opt(int key, } for(token = strtok_r(arg, ",", &ptr), i = 0; - token != NULL, i < 4; + token != NULL && i < 4; token = strtok_r(NULL, ",", &ptr), i++) { if (strcasecmp(token, "leGall") == 0) @@ -1047,6 +1045,7 @@ parse_opt(int key, { if (arguments->mode == cli_ini) argp_usage (state); + break; } /* Return error if key is unknown. */ @@ -1061,7 +1060,7 @@ parse_opt(int key, * @details Initialize the argp struct. used to parse the command line arguments */ /*================================================================================================*/ -static struct argp argp = {options, parse_opt, 0, doc}; +static struct argp argp = {options, parse_opt, 0, doc, 0, 0, 0}; /*================================================================================================*/ /** @@ -1087,7 +1086,7 @@ int main(int argc, char *argv[]) \*-----------------------*/ uint64_t size = 0; uint8_t i; - uint8_t error_handle; + uint8_t error_handle = EXIT_SUCCESS; /*-----------------------*\ ! DEFINE REAL VARIABLES: ! @@ -1101,28 +1100,28 @@ int main(int argc, char *argv[]) char cli_buffer[1024] = {0}; char cli_verbose[4096] = {0}; - char *cli_output; - char *buffer; + char *cli_output = NULL; + char *buffer = NULL; - unsigned char *input; - unsigned char *output; + unsigned char *input = NULL; + unsigned char *output = NULL; /*-----------------------*\ ! DEFINE FILE POINTER: ! \*-----------------------*/ - FILE *fp; + FILE *fp = NULL; /*-----------------------*\ ! DEFINE DER. VARIABLES: ! \*-----------------------*/ bwc_precision precision; - bwc_stream *stream; - bwc_codec *coder; + bwc_stream *stream = NULL; + bwc_codec *coder = NULL; /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - eas3_data *data; + eas3_data *data = NULL; cli_arguments arguments = {0}; /* Parse the command line arguments and invoke the appro- * @@ -1173,7 +1172,7 @@ int main(int argc, char *argv[]) printf(TYPERROR); goto OUT; } - cli_output = calloc(strlen(arguments.out) - strlen(buffer) + 1, sizeof(char)); + cli_output = calloc(strlen(arguments.out) - strlen(buffer) + 5, sizeof(char)); if (cli_output == NULL) { error_handle = EXIT_FAILURE; @@ -1471,5 +1470,8 @@ OUT: if (cli_output != NULL) free(cli_output); + if (fp != NULL) + fclose(fp); + return error_handle; } -- 2.45.2 From 92a646b5e09aad0272417e5bdbca8d6fb9fb911f Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Thu, 31 Oct 2024 14:31:34 +0100 Subject: [PATCH 06/21] refactor and typos --- src/interfaces/reader/eas3.c | 4 ++-- src/tools/bwccmdl.c | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/interfaces/reader/eas3.c b/src/interfaces/reader/eas3.c index b5a3554..868f1bf 100644 --- a/src/interfaces/reader/eas3.c +++ b/src/interfaces/reader/eas3.c @@ -223,8 +223,8 @@ endian_conversion(void *value, ! ! ! DESCRIPTION: ! ! ------------ ! -! This function deallocates the data structure used to store an numerical dataset ! -! and can be called if an error occurs or once the data is no longer needed is to be closed. ! +! This function deallocates the data structure used to store a numerical dataset ! +! and can be called if an error occurs or once the data is no longer needed. ! ! The deallocation will be carried out down to the structure levels that have been allocated. ! ! ! \*----------------------------------------------------------------------------------------------------------*/ diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index db9f10e..8df4e9c 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -153,7 +153,7 @@ static char bwc_header[] = "==================================================== */ /*================================================================================================*/ const char *argp_program_version = "bwc 0.1.0"; -const char *argp_program_bug_address = "hpcpvogl@hlrs.de"; +const char *argp_program_bug_address = "patrick.vogler@hlrs.de"; /*================================================================================================*/ /** @@ -614,7 +614,7 @@ parse_opt(int key, if (verify_opt(arg, ',', true) == EXIT_FAILURE) { - argp_error(state, "Invalid delimitnator in the bitrate option\n"); + argp_error(state, "Invalid deliminator in the bitrate option\n"); } for(bitrate = strtod(arg, &end), i = 0; arg != end && i < 10; @@ -648,7 +648,7 @@ parse_opt(int key, if (verify_opt(arg, ',', false) == EXIT_FAILURE) { - argp_error(state, "Invalid delimitnator in the codeblock" + argp_error(state, "Invalid deliminator in the codeblock" " size option.\n"); } @@ -702,7 +702,7 @@ parse_opt(int key, if (verify_opt(arg, ',', true) == EXIT_FAILURE) { - argp_error(state, "Invalid delimitnator in the compression" + argp_error(state, "Invalid deliminator in the compression" " ratio option \n"); } @@ -737,7 +737,7 @@ parse_opt(int key, if (verify_opt(arg, ',', false) == EXIT_FAILURE) { - argp_error(state, "Invalid delimitnator in the decomposition" + argp_error(state, "Invalid deliminator in the decomposition" " level option.\n"); } @@ -933,7 +933,7 @@ parse_opt(int key, if (verify_opt(arg, ',', false) == EXIT_FAILURE) { - argp_error(state, "Invalid delimitnator in the tile" + argp_error(state, "Invalid deliminator in the tile" " size option.\n"); } @@ -981,7 +981,7 @@ parse_opt(int key, if (verify_opt(arg, ',', false) == EXIT_FAILURE) { - argp_error(state, "Invalid delimitnator in the precinct" + argp_error(state, "Invalid deliminator in the precinct" " size option.\n"); } @@ -1189,7 +1189,7 @@ int main(int argc, char *argv[]) } /* Evaluate the input and output buffer size and initial- * - * ize the BigWhoop data and coder structs. */ + * size the BigWhoop data and coder structs. */ size = data->params.ndim1 * data->params.ndim2 * data->params.ndim3 * data->params.nts * data->params.npar; -- 2.45.2 From 12f937ecac54703f20d9e51ecbb38955a61cd6b9 Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Mon, 4 Nov 2024 13:57:33 +0100 Subject: [PATCH 07/21] open and close header with new header structure --- include/library/private/codestream.h | 4 ++ include/library/private/libbwc.h | 4 ++ include/library/private/types.h | 13 ++++ src/library/codestream.c | 2 +- src/library/libbwc.c | 92 ++++++++++++++++++++++++++++ src/tools/bwccmdl.c | 26 ++++---- 6 files changed, 127 insertions(+), 14 deletions(-) diff --git a/include/library/private/codestream.h b/include/library/private/codestream.h index 0445b59..2e022aa 100755 --- a/include/library/private/codestream.h +++ b/include/library/private/codestream.h @@ -100,6 +100,10 @@ size_t assemble_codestream (bwc_codec *const codec, bwc_stream *const stream); //==========|==========================|======================|======|======|===================== + bwc_codec* parse_main_header (bwc_codec *const codec, + bwc_stream *const data, + bitstream *const stream); + //==========|==========================|======================|======|======|===================== bwc_codec* parse_codestream (bwc_codec *const codec, bwc_stream *const stream, uint8 const layer); diff --git a/include/library/private/libbwc.h b/include/library/private/libbwc.h index 5d67736..1afab38 100755 --- a/include/library/private/libbwc.h +++ b/include/library/private/libbwc.h @@ -142,6 +142,10 @@ uint64 const tilesTS, bwc_tile_instr const instr); //==========|==========================|======================|======|=======|==================== + bwc_header* bwc_open_header (void *const inpbuf); + //==========|==========================|======================|======|=======|==================== + void bwc_close_header (bwc_header *const header); + //==========|==========================|======================|======|=======|==================== uchar bwc_create_compression (bwc_codec *const codec, bwc_stream *const data, char *const rate_control); diff --git a/include/library/private/types.h b/include/library/private/types.h index 0320a8e..bba676d 100755 --- a/include/library/private/types.h +++ b/include/library/private/types.h @@ -659,6 +659,19 @@ bwc_prog_ord progression; // Packet progression order. } bwc_gl_ctrl; +/*================================================================================================*/ +/** + * @details Structure that is used to probe header information from a compressed data set. + */ +/*================================================================================================*/ + typedef struct + { + bwc_gl_inf info; // Global info structure + bwc_gl_ctrl control; // Global control structure + bwc_span aux; // Auxiliary info. codestream block. + bwc_span com; // Comment codestream block. + } bwc_header; + /*----------------------------------------------------------------------------------------------*\ ! ! ! DESCRIPTION: ! diff --git a/src/library/codestream.c b/src/library/codestream.c index 3c0d8d3..aec991c 100755 --- a/src/library/codestream.c +++ b/src/library/codestream.c @@ -912,7 +912,7 @@ parse_main_header(bwc_codec *const codec, bwc_stream *const data, bitstream *con data->codestream.com->memory = get_chunck(stream, Lcom - 2); data->codestream.com->size = Lcom -2; - status |= CODESTREAM_ERROR; + status |= CODESTREAM_COM_READ; break; } diff --git a/src/library/libbwc.c b/src/library/libbwc.c index d6ede6f..0beb985 100755 --- a/src/library/libbwc.c +++ b/src/library/libbwc.c @@ -3350,6 +3350,98 @@ bwc_set_tiles(bwc_codec *const codec, uint64 tilesX, uint64 tilesY, uint64 tiles control->CSsgc |= (0x01 << 9); } +/*================================================================================================*/ +/** + * @details This function opens the header of a compressed data set and parses it into an + * instance of type bwc_header. + * + * @param[in] inpbuf Pointer to compressed data set. + * + * @retval bwc_header* + */ +/*================================================================================================*/ +bwc_header* bwc_open_header(void *const inpbuf) +{ + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + bwc_codec* codec; + bwc_stream* data; + bitstream* stream; + bwc_header* header; + + /*--------------------------------------------------------*\ + ! Initialize a codec, stream, and bitstream for parsing. ! + \*--------------------------------------------------------*/ + data = bwc_init_stream(inpbuf, NULL, decomp); + codec = bwc_alloc_decoder(); + stream = init_bitstream(data->inp, 10, 'd'); + + /*--------------------------------------------------------*\ + ! Parse the main header into the codec structure. ! + \*--------------------------------------------------------*/ + parse_main_header(codec, data, stream); + if(!codec) + { + return NULL; + } + + /*--------------------------------------------------------*\ + ! Allocate header and copy info and control structures. ! + \*--------------------------------------------------------*/ + header = calloc(1, sizeof(bwc_header)); + header->info = codec->info; + header->control = codec->control; + + /*--------------------------------------------------------*\ + ! Shallow copy aux data to span. ! + \*--------------------------------------------------------*/ + if (data->codestream.aux) + { + header->aux.memory = data->codestream.aux->memory; + header->aux.size = data->codestream.aux->size; + } + + /*--------------------------------------------------------*\ + ! Shallow copy com data to span. ! + \*--------------------------------------------------------*/ + if (data->codestream.com) + { + header->com.memory = data->codestream.com->memory; + header->com.size = data->codestream.com->size; + } + + free(stream); + free(data); + free(codec); + + return header; +} + +/*================================================================================================*/ +/** + * @details This function closes the header information in the bwc_header pointer. + * + * @param[in] header Instance of type bwc_header. + */ +/*================================================================================================*/ +void bwc_close_header(bwc_header *const header) +{ + if (header) + { + if (header->aux.memory) + { + free(header->aux.memory); + } + if (header->com.memory) + { + free(header->com.memory); + } + free(header); + } +} + + /*----------------------------------------------------------------------------------------------------------*\ ! FUNCTION NAME: void bwc_create_compression(bwc_codec *codec, char *rate_control) ! ! -------------- ! diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index 8df4e9c..8ec216f 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -134,18 +134,18 @@ * @details String containing the header used for the cli output. */ /*================================================================================================*/ -static char bwc_header[] = "==============================================================\n"\ - " \n"\ - " .:-------------: .:-------------: \n"\ - " .+++++++++++++++= :+++++++++++++++- \n"\ - " :+++. -++= -++= \n"\ - " :+++. -++= -++= \n"\ - " -++++++++++++++= -++= -++= \n"\ - " .=++---------=++= -++= -++= \n"\ - " :+++ :++= -++= -++= \n"\ - " .+++=--------=+++---=+++---=+++------------: \n"\ - " -=++++++++++++++++++++++++++++++++++++++++- \n"\ - " \n"; +static char bwc_header_art[] = "==============================================================\n"\ + " \n"\ + " .:-------------: .:-------------: \n"\ + " .+++++++++++++++= :+++++++++++++++- \n"\ + " :+++. -++= -++= \n"\ + " :+++. -++= -++= \n"\ + " -++++++++++++++= -++= -++= \n"\ + " .=++---------=++= -++= -++= \n"\ + " :+++ :++= -++= -++= \n"\ + " .+++=--------=+++---=+++---=+++------------: \n"\ + " -=++++++++++++++++++++++++++++++++++++++++- \n"\ + " \n"; /*================================================================================================*/ /** @@ -1153,7 +1153,7 @@ int main(int argc, char *argv[]) } if (arguments.verbose == true) { - strcat(cli_verbose, bwc_header); + strcat(cli_verbose, bwc_header_art); strcat(cli_verbose, "--------------------------- I/O --------------------------\n\n"); sprintf(cli_buffer," Input: %s \n", arguments.in); -- 2.45.2 From d631f693c966e5b1693f59dbacceee4d2a11bee1 Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Mon, 4 Nov 2024 15:45:14 +0100 Subject: [PATCH 08/21] initial decompression workflow in cmdl tool --- src/tools/bwccmdl.c | 119 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 2 deletions(-) diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index 8ec216f..d408b3f 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -78,6 +78,10 @@ "| ERROR: Invalid file type. |\n"\ "o##########################################################o\n" +#define FINERROR "o##########################################################o\n"\ + "| ERROR: Could not open specified input file. |\n"\ + "o##########################################################o\n" + #define FOUERROR "o##########################################################o\n"\ "| ERROR: Could not open specified output file. |\n"\ "o##########################################################o\n" @@ -1085,6 +1089,7 @@ int main(int argc, char *argv[]) ! DEFINE INT VARIABLES: ! \*-----------------------*/ uint64_t size = 0; + uint64_t root, Lfield; uint8_t i; uint8_t error_handle = EXIT_SUCCESS; @@ -1115,6 +1120,7 @@ int main(int argc, char *argv[]) ! DEFINE DER. VARIABLES: ! \*-----------------------*/ bwc_precision precision; + bwc_header *header; bwc_stream *stream = NULL; bwc_codec *coder = NULL; @@ -1165,7 +1171,6 @@ int main(int argc, char *argv[]) if ((arguments.optSet & FLOUT) == 0) arguments.out = arguments.in; - printf("%s \n", arguments.out); if ((buffer = strrchr(arguments.out, '.')) == NULL) { error_handle = EXIT_FAILURE; @@ -1439,7 +1444,117 @@ int main(int argc, char *argv[]) } else if (arguments.mode == cli_dcp) { - printf("Decompression\n"); + if ((fp = fopen(arguments.in, "r")) == NULL) + { + error_handle = EXIT_FAILURE; + printf(FINERROR); + goto OUT; + } + + root = ftell(fp); + fseek(fp, 0L, SEEK_END); + Lfield = ftell(fp) - root; + fseek(fp, root, SEEK_SET); + + if (arguments.verbose == true) + { + strcat(cli_verbose, bwc_header_art); + strcat(cli_verbose, "--------------------------- I/O --------------------------\n\n"); + + sprintf(cli_buffer," Input: %s \n", arguments.in); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + } + + /* Evaluate the appropriate output file. */ + if ((arguments.optSet & FLOUT) == 0) + arguments.out = arguments.in; + + if ((buffer = strrchr(arguments.out, '.')) == NULL) + { + error_handle = EXIT_FAILURE; + printf(TYPERROR); + goto OUT; + } + cli_output = calloc(strlen(arguments.out) - strlen(buffer) + 5, sizeof(char)); + if (cli_output == NULL) + { + error_handle = EXIT_FAILURE; + printf(MEMERROR); + goto OUT; + } + sprintf(cli_output, "%.*s.eas", (int)(strlen(arguments.out) - strlen(buffer)), arguments.out); + + if (arguments.verbose == true) + { + sprintf(cli_buffer," Output: %s \n", cli_output); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + } + + if ((arguments.verbose == true) && + (delim == true)) + { + + strcat(cli_verbose, " __________________________________________________________\n"); + strcat(cli_verbose, "\n"); + } + + if (arguments.verbose == true) + { + memset(cli_buffer, '0', sizeof(char) * 1024); + strcat(cli_verbose, "\n==============================================================\n"); + printf("%s", cli_verbose); + } + + /* Read the codestream from the specified file. */ + input = calloc(Lfield, sizeof(uchar)); + if (fread(input, sizeof(uchar), Lfield, fp) != Lfield) + { + error_handle = EXIT_FAILURE; + printf(RDERROR); + goto OUT; + } + + header = bwc_open_header(input); + + size = header->info.nX * header->info.nY * header->info.nZ * + header->info.nTS * header->info.nPar; + + if(header->info.data_prec == bwc_precision_double) + { + output = calloc(size, sizeof(double)); + } + else if(header->info.data_prec == bwc_precision_single) + { + output = calloc(size, sizeof(float)); + } + + bwc_close_header(header); + + stream = bwc_init_stream(input, output, comp); + coder = bwc_alloc_decoder(); + + //if (arguments.verbose == true) + //{ + //memset(cli_buffer, '0', sizeof(char) * 1024); + //strcat(cli_verbose, "\n==============================================================\n"); + //printf("%s", cli_verbose); + //} + + /* Initialize the rate control string according to the * + * specified bit rate/compression ratio. */ + if (bwc_create_decompression(coder, stream, 0) == EXIT_FAILURE) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + + size = bwc_decompress(coder, stream); + + //write_eas3(output, cli_output); + + goto OUT; } else if (arguments.mode == cli_anl) { -- 2.45.2 From d1bfb5236afc49ac33ffde2495774688590b465e Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Tue, 5 Nov 2024 11:07:24 +0100 Subject: [PATCH 09/21] fill eas3_data form bwc_stream and bwc_codec --- src/tools/bwccmdl.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index d408b3f..cf7a4cc 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -1550,9 +1550,32 @@ int main(int argc, char *argv[]) goto OUT; } - size = bwc_decompress(coder, stream); + bwc_decompress(coder, stream); - //write_eas3(output, cli_output); + size = coder->info.nX * coder->info.nY * coder->info.nZ * + coder->info.nTS * coder->info.nPar; + + data->params.ndim1 = coder->info.nX; + data->params.ndim2 = coder->info.nY; + data->params.ndim3 = coder->info.nZ; + data->params.nts = coder->info.nTS; + data->params.npar = coder->info.nPar; + if (coder->info.data_prec == bwc_precision_single) + { + data->params.accuracy = 1; + data->field.d = NULL; + data->field.f = calloc(size, sizeof(float)); + memcpy(data->field.f, stream->out, size); + } + else if (coder->info.data_prec == bwc_precision_double) + { + data->params.accuracy = 2; + data->field.f = NULL; + data->field.d = calloc(size, sizeof(double)); + memcpy(data->field.d, stream->out, size); + } + + //write_eas3(data, cli_output); goto OUT; } -- 2.45.2 From 9167ec48f3062a62e9266ee7d5a1d603264db427 Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Tue, 5 Nov 2024 11:09:13 +0100 Subject: [PATCH 10/21] doxygen in types.h --- include/library/private/types.h | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/include/library/private/types.h b/include/library/private/types.h index bba676d..06b49b6 100755 --- a/include/library/private/types.h +++ b/include/library/private/types.h @@ -672,18 +672,12 @@ bwc_span com; // Comment codestream block. } bwc_header; - /*----------------------------------------------------------------------------------------------*\ - ! ! - ! 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. ! - ! ! - \*----------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Structure holding all the necessary parameters defining and controlling a bwc + * (de-)compression run. + */ +/*================================================================================================*/ typedef struct { bwc_gl_inf info; // Global info structure -- 2.45.2 From 55ad00d6c5fdb33d17008dc3484e2b5be9d81cd1 Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Tue, 5 Nov 2024 11:10:00 +0100 Subject: [PATCH 11/21] fill eas3 auxiliary information in cmdl tool compression --- src/tools/bwccmdl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index cf7a4cc..38de588 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -1416,6 +1416,8 @@ int main(int argc, char *argv[]) printf("%s", cli_verbose); } + bwc_set_aux(stream, (char*)data->aux.ptr, data->aux.len); + /* Initialize the rate control string according to the * * specified bit rate/compression ratio. */ if (bwc_create_compression(coder, stream, rate) == EXIT_FAILURE) -- 2.45.2 From 5d5aafae37bb456ccaaf78897eb78003fdac5d48 Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Tue, 5 Nov 2024 11:12:12 +0100 Subject: [PATCH 12/21] bug fixes in bwc_set_aux and bwc_set_com, both missing allocation of bwc_span --- src/library/libbwc.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/library/libbwc.c b/src/library/libbwc.c index 0beb985..b886f64 100755 --- a/src/library/libbwc.c +++ b/src/library/libbwc.c @@ -1498,8 +1498,9 @@ bwc_set_com(bwc_stream *const data, char const *const com, uint16 size) ! Save the global info structure to a temporary variable ! ! to make the code more readable. ! \*--------------------------------------------------------*/ + data->codestream.com = calloc(1, sizeof(bwc_span)); data->codestream.com->memory = calloc(size, sizeof(char)); - if(!data->codestream.com->memory) + if(!data->codestream.com->memory) { // memory allocation error fprintf(stderr, MEMERROR); @@ -1536,18 +1537,19 @@ bwc_set_aux(bwc_stream *const data, char const *const aux, uint32 size) ! Save the global info structure to a temporary variable ! ! to make the code more readable. ! \*--------------------------------------------------------*/ - data->codestream.com->memory = calloc(size, sizeof(char)); - if(!data->codestream.com->memory) + data->codestream.aux = calloc(1, sizeof(bwc_span)); + data->codestream.aux->memory = calloc(size, sizeof(char)); + if(!data->codestream.aux->memory) { // memory allocation error fprintf(stderr, MEMERROR); return 1; } - memcpy(data->codestream.com->memory, aux, size * sizeof(char)); - data->codestream.com->access = data->codestream.com->memory; - data->codestream.com->size = size; - data->codestream.com->position = 0; + memcpy(data->codestream.aux->memory, aux, size * sizeof(char)); + data->codestream.aux->access = data->codestream.aux->memory; + data->codestream.aux->size = size; + data->codestream.aux->position = 0; return 0; } -- 2.45.2 From d13354078bcac21d933f70328cedc09caa03ec7f Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Tue, 5 Nov 2024 18:43:45 +0100 Subject: [PATCH 13/21] enqueue parameter names in auxiliary information --- src/interfaces/reader/eas3.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/interfaces/reader/eas3.c b/src/interfaces/reader/eas3.c index 868f1bf..8b817ba 100644 --- a/src/interfaces/reader/eas3.c +++ b/src/interfaces/reader/eas3.c @@ -582,13 +582,9 @@ read_eas3_header(FILE *const fp, eas3_data *const data) return 1; } + aux_enqueue(data->aux, param_name, ATTRLEN * sizeof(char)); eas3_add_param_name(data, param_name); - /*--------------------------------------------------------*\ - ! 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); } } -- 2.45.2 From d4acd85c37eac35c6ee1eb1ad46b339202bc4e97 Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Tue, 5 Nov 2024 18:45:40 +0100 Subject: [PATCH 14/21] bwc_to_eas3 and writing decompressed data, tested output can be parsed to compress again --- include/interfaces/reader/eas3.h | 3 + src/interfaces/reader/eas3.c | 120 +++++++++++++++++++++++++++++++ src/tools/bwccmdl.c | 27 +------ 3 files changed, 126 insertions(+), 24 deletions(-) diff --git a/include/interfaces/reader/eas3.h b/include/interfaces/reader/eas3.h index c7d647b..266d91c 100644 --- a/include/interfaces/reader/eas3.h +++ b/include/interfaces/reader/eas3.h @@ -359,6 +359,9 @@ void eas3_free_data(eas3_data* data); + uchar + bwc_to_eas3(bwc_stream *const stream, eas3_data *const data); + /*----------------------------------------------------------------------------------------------------------*\ ! FUNCTION NAME: bwc_data* read_eas3(const char* const filename) ! ! -------------- ! diff --git a/src/interfaces/reader/eas3.c b/src/interfaces/reader/eas3.c index 8b817ba..8bc999e 100644 --- a/src/interfaces/reader/eas3.c +++ b/src/interfaces/reader/eas3.c @@ -317,6 +317,118 @@ eas3_add_param_name(eas3_data *const data, char *name) strcpy(data->param_names->name, name ? name : "undefined"); } +/*================================================================================================*/ +/** + * @details Parses the uncompressed output from bwc_stream into the eas3_data. + * + * @param[in] stream Pointer to uncompressed data set. + * @param[inout] data Pointer to eas3_data structure to be filled. + * + * @retval uchar + */ +/*================================================================================================*/ +uchar +bwc_to_eas3(bwc_stream *const stream, eas3_data *const data) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 Lread; + uint64 size; + uint64 i; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + uchar *buffer_char; + char param_name[ATTRLEN + 1] = {}; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + eas3_std_params *params; + + params = &data->params; + + data->aux.ptr = calloc(stream->codestream.aux->size, sizeof(uchar)); + data->aux.pos = 0; + data->aux.len = stream->codestream.aux->size; + if(!data->aux.ptr) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(data->aux.ptr); + return 1; + } + memcpy(data->aux.ptr, stream->codestream.aux->memory, + stream->codestream.aux->size); + + aux_dequeue(data->aux, (uchar*)params, 176); + + endian_conversion(¶ms->nts, 8); + endian_conversion(¶ms->npar, 8); + endian_conversion(¶ms->ndim1, 8); + endian_conversion(¶ms->ndim2, 8); + endian_conversion(¶ms->ndim3, 8); + endian_conversion(¶ms->accuracy, 8); + if(params->accuracy != 1 && params->accuracy != 2) + { + 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; + } + + buffer_char = calloc(params->nts, sizeof(uint64)); + if(!buffer_char) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(buffer_char); + return 1; + } + aux_dequeue(data->aux, buffer_char, params->nts * sizeof(uint64)); + + if(params->attribute_mode == EAS3_ALL_ATTR) + { + buffer_char = realloc(buffer_char, params->nts * ATTRLEN * sizeof(char)); + if(!buffer_char) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(buffer_char); + return 1; + } + aux_dequeue(data->aux, buffer_char, params->nts * ATTRLEN * sizeof(char)); + + for(i = 0; i < params->npar; ++i) + { + aux_dequeue(data->aux, param_name, ATTRLEN * sizeof(char)); + eas3_add_param_name(data, param_name); + memset(param_name, 0, ATTRLEN + 1); + } + } + + size = params->ndim1 * params->ndim2 * params->ndim3 * + params->nts * params->npar; + + if(params->accuracy == 1) + { + data->field.d = NULL; + data->field.f = calloc(size, sizeof(float)); + memcpy(data->field.f, stream->out, size); + } + else if(params->accuracy == 2) + { + data->field.f = NULL; + data->field.d = calloc(size, sizeof(double)); + memcpy(data->field.d, stream->out, size); + } + + return 0; +} + /*----------------------------------------------------------------------------------------------------------*\ ! FUNCTION NAME: uchar read_eas3_header(bwc_data *const data) ! ! -------------- ! @@ -756,7 +868,13 @@ write_eas3_header(FILE *const fp, eas3_data *const data) ! Convert the size parameters, used to write the rest of ! ! the header, to little endian. ! \*--------------------------------------------------------*/ + endian_conversion(¶ms->file_type, 8); endian_conversion(¶ms->accuracy, 8); + endian_conversion(¶ms->nts, 8); + endian_conversion(¶ms->npar, 8); + endian_conversion(¶ms->ndim1, 8); + endian_conversion(¶ms->ndim2, 8); + endian_conversion(¶ms->ndim3, 8); endian_conversion(¶ms->size_time, 8); endian_conversion(¶ms->size_parameter, 8); endian_conversion(¶ms->size_dim1, 8); @@ -766,6 +884,8 @@ write_eas3_header(FILE *const fp, eas3_data *const data) endian_conversion(¶ms->udef_int_size, 8); endian_conversion(¶ms->udef_real_size, 8); + data->params = *params; + /*--------------------------------------------------------*\ ! Allocate the buffer character array. If successful, get ! ! the timestep array from the auxiliary information block ! diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index 38de588..2651b2c 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -1554,30 +1554,9 @@ int main(int argc, char *argv[]) bwc_decompress(coder, stream); - size = coder->info.nX * coder->info.nY * coder->info.nZ * - coder->info.nTS * coder->info.nPar; - - data->params.ndim1 = coder->info.nX; - data->params.ndim2 = coder->info.nY; - data->params.ndim3 = coder->info.nZ; - data->params.nts = coder->info.nTS; - data->params.npar = coder->info.nPar; - if (coder->info.data_prec == bwc_precision_single) - { - data->params.accuracy = 1; - data->field.d = NULL; - data->field.f = calloc(size, sizeof(float)); - memcpy(data->field.f, stream->out, size); - } - else if (coder->info.data_prec == bwc_precision_double) - { - data->params.accuracy = 2; - data->field.f = NULL; - data->field.d = calloc(size, sizeof(double)); - memcpy(data->field.d, stream->out, size); - } - - //write_eas3(data, cli_output); + data = calloc(1, sizeof(eas3_data)); + bwc_to_eas3(stream, data); + write_eas3(data, cli_output); goto OUT; } -- 2.45.2 From 1a087c1c857bf518a44b5a08192593280cce0d08 Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Wed, 6 Nov 2024 15:42:56 +0100 Subject: [PATCH 15/21] Update docstrings in eas3.c --- src/interfaces/reader/eas3.c | 260 ++++++++++------------------------- 1 file changed, 75 insertions(+), 185 deletions(-) diff --git a/src/interfaces/reader/eas3.c b/src/interfaces/reader/eas3.c index 8bc999e..f3e2985 100644 --- a/src/interfaces/reader/eas3.c +++ b/src/interfaces/reader/eas3.c @@ -102,15 +102,11 @@ || | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || || || \************************************************************************************************************/ - -/*----------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This macro is used to write an additional chunck of size length to the auxilliary ! -! information. ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Enqueues a chunck of size length to the auxilliary information. + */ +/*================================================================================================*/ #define aux_enqueue(aux, chunck, chunck_len) \ { \ if (aux.pos + chunck_len > aux.len) \ @@ -125,6 +121,11 @@ aux.pos += chunck_len; \ } +/*================================================================================================*/ +/** + * @details Dequeues a chunck of size length from the auxilliary information. + */ +/*================================================================================================*/ #define aux_dequeue(aux, chunck, chunck_len) \ { \ if(aux.pos + chunck_len <= aux.len) { \ @@ -135,37 +136,14 @@ } \ } -/*----------------------------------------------------------------------------------------------------------*\ -! ! -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Converts the endianess of half, single, or double precision values. + * + * @param[inout] value Pointer to the parameter to be converted. + * @param[in] accuracy Precision/accuracy of the pointed parameter. + */ +/*================================================================================================*/ static void endian_conversion(void *value, uint8_t const accuracy) @@ -219,15 +197,13 @@ endian_conversion(void *value, } } -/*----------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function deallocates the data structure used to store a numerical dataset ! -! and can be called if an error occurs or once the data is no longer needed. ! -! The deallocation will be carried out down to the structure levels that have been allocated. ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Deallocates the provided eas3_data structure including all contained data. + * + * @param[in] data Pointer to eas3_data structure to be filled. + */ +/*================================================================================================*/ void eas3_free_data(eas3_data* data) { @@ -263,6 +239,14 @@ eas3_free_data(eas3_data* data) } } +/*================================================================================================*/ +/** + * @details Adds a parameter name to the linked list inside the eas3_data structure. + * + * @param[in] data Pointer to eas3_data structure to be filled. + * @param[in] name Name to be added to the linked list. + */ +/*================================================================================================*/ void eas3_add_param_name(eas3_data *const data, char *name) { @@ -429,40 +413,17 @@ bwc_to_eas3(bwc_stream *const stream, eas3_data *const data) return 0; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar read_eas3_header(bwc_data *const data) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function opens an eas3 file and checks it for its validity. Once the specified file ! -! has been verified, its header and flow field data is read and stored in the bwc_data ! -! structure. ! -! ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! filename char* - Defines the filename of the eas3 file ! -! that is to be opened and read. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! file - Defines a structure used to store all ! -! the relevant parameters and the data ! -! field of an eas3 file. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Reads the header from an open eas3 file pointer parsing the header information into + * the eas3_data structure argument. + * + * @param[in] fp Readily opened file pointer. + * @param[inout] data Structure to store eas3 data. + * + * @retval uchar + */ +/*================================================================================================*/ static uchar read_eas3_header(FILE *const fp, eas3_data *const data) { @@ -772,40 +733,17 @@ read_eas3_header(FILE *const fp, eas3_data *const data) return 0; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar read_eas3_header(bwc_data *const data) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function opens an eas3 file and checks it for its validity. Once the specified file ! -! has been verified, its header and flow field data is read and stored in the bwc_data ! -! structure. ! -! ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! filename char* - Defines the filename of the eas3 file ! -! that is to be opened and read. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! file - Defines a structure used to store all ! -! the relevant parameters and the data ! -! field of an eas3 file. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Writes the header information from the eas3_data structure into the open eas3 + * file pointer. + * + * @param[in] fp Readily opened file pointer. + * @param[inout] data Structure to store eas3 data. + * + * @retval uchar + */ +/*================================================================================================*/ static uchar write_eas3_header(FILE *const fp, eas3_data *const data) { @@ -1019,40 +957,16 @@ write_eas3_header(FILE *const fp, eas3_data *const data) || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || || || \************************************************************************************************************/ -/*----------------------------------------------------------------------------------------------------------*\ -! 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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Opens an eas3 file and checks it for its validity. Then, it reads header and flow + * field data and returns a filled instance of the eas3_data structure. + * + * @param[in] filename Name of the eas3 file. + * + * @retval eas3_data* + */ +/*================================================================================================*/ eas3_data* read_eas3(char *const filename) { @@ -1215,40 +1129,16 @@ read_eas3(char *const filename) return data; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar write_eas3(bwc_data *const file, char *const filename) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function creates a valid eas3 file from the information stored in the bwc_data ! -! structure. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! filename char* - Defines the filename of the eas3 file ! -! that is to be opened and read. ! -! ! -! file bwc_data* - Defines a structure used to store all ! -! the relevant parameters and the data ! -! field of an eas3 file. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! uchar - Returns an unsigned char for error handling. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Opens an eas3 file and writes the content from the provided eas3_data structure. + * + * @param[in] data Data to be written into the eas3 file. + * @param[in] filename Name of the eas3 file. + * + * @retval uchar + */ +/*================================================================================================*/ uchar write_eas3(eas3_data *const data, char *const filename) { -- 2.45.2 From acf703f6502efa1ef869068af0380a1c0cdc59b1 Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Wed, 6 Nov 2024 17:23:09 +0100 Subject: [PATCH 16/21] refactor/clean up in cmdl tool --- src/tools/bwccmdl.c | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index 2651b2c..20a1ce9 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -1219,6 +1219,7 @@ int main(int argc, char *argv[]) data->params.nts, data->params.npar, precision); + bwc_set_aux(stream, (char*)data->aux.ptr, data->aux.len); /* Apply the user supplied compression options using the * * appropriate setter functions. */ @@ -1416,8 +1417,6 @@ int main(int argc, char *argv[]) printf("%s", cli_verbose); } - bwc_set_aux(stream, (char*)data->aux.ptr, data->aux.len); - /* Initialize the rate control string according to the * * specified bit rate/compression ratio. */ if (bwc_create_compression(coder, stream, rate) == EXIT_FAILURE) @@ -1494,14 +1493,6 @@ int main(int argc, char *argv[]) memset(cli_buffer, '0', sizeof(char) * 1024); } - if ((arguments.verbose == true) && - (delim == true)) - { - - strcat(cli_verbose, " __________________________________________________________\n"); - strcat(cli_verbose, "\n"); - } - if (arguments.verbose == true) { memset(cli_buffer, '0', sizeof(char) * 1024); @@ -1509,7 +1500,7 @@ int main(int argc, char *argv[]) printf("%s", cli_verbose); } - /* Read the codestream from the specified file. */ + /* Read the compressed data from the input file. */ input = calloc(Lfield, sizeof(uchar)); if (fread(input, sizeof(uchar), Lfield, fp) != Lfield) { @@ -1518,11 +1509,10 @@ int main(int argc, char *argv[]) goto OUT; } + /* Retrieve header information and allocate output buffer. */ header = bwc_open_header(input); - size = header->info.nX * header->info.nY * header->info.nZ * header->info.nTS * header->info.nPar; - if(header->info.data_prec == bwc_precision_double) { output = calloc(size, sizeof(double)); @@ -1531,29 +1521,20 @@ int main(int argc, char *argv[]) { output = calloc(size, sizeof(float)); } - bwc_close_header(header); + /* Initialize and run the decompression. */ stream = bwc_init_stream(input, output, comp); coder = bwc_alloc_decoder(); - - //if (arguments.verbose == true) - //{ - //memset(cli_buffer, '0', sizeof(char) * 1024); - //strcat(cli_verbose, "\n==============================================================\n"); - //printf("%s", cli_verbose); - //} - - /* Initialize the rate control string according to the * - * specified bit rate/compression ratio. */ if (bwc_create_decompression(coder, stream, 0) == EXIT_FAILURE) { error_handle = EXIT_FAILURE; goto OUT; } - bwc_decompress(coder, stream); + /* Parse decompressed data into eas3 data structure * + * and write to the output file. */ data = calloc(1, sizeof(eas3_data)); bwc_to_eas3(stream, data); write_eas3(data, cli_output); -- 2.45.2 From 6176fea67667d79931cdd4f0ea1908321626284d Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Thu, 7 Nov 2024 10:32:38 +0100 Subject: [PATCH 17/21] header info mode --- src/tools/bwccmdl.c | 115 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index 20a1ce9..c85ce50 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -1547,7 +1547,120 @@ int main(int argc, char *argv[]) } else if (arguments.mode == cli_inf) { - printf("Header Info\n"); + strcat(cli_verbose, bwc_header_art); + strcat(cli_verbose, "--------------------------- I/O --------------------------\n\n"); + sprintf(cli_buffer," Input: %s \n", arguments.in); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + if ((fp = fopen(arguments.in, "r")) == NULL) + { + error_handle = EXIT_FAILURE; + printf(FINERROR); + goto OUT; + } + + root = ftell(fp); + fseek(fp, 0L, SEEK_END); + Lfield = ftell(fp) - root; + fseek(fp, root, SEEK_SET); + + /* Read the compressed data from the input file. */ + input = calloc(Lfield, sizeof(uchar)); + if (fread(input, sizeof(uchar), Lfield, fp) != Lfield) + { + error_handle = EXIT_FAILURE; + printf(RDERROR); + goto OUT; + } + + /* Retrieve header information and allocate output buffer. */ + header = bwc_open_header(input); + size = header->info.nX * header->info.nY * header->info.nZ * + header->info.nTS * header->info.nPar; + if(header->info.data_prec == bwc_precision_double) + { + output = calloc(size, sizeof(double)); + } + else if(header->info.data_prec == bwc_precision_single) + { + output = calloc(size, sizeof(float)); + } + bwc_close_header(header); + + strcat(cli_verbose, "\n"); + strcat(cli_verbose, "----------------- Compression Parameters -----------------\n"); + strcat(cli_verbose, "\n"); + + strcat(cli_verbose," Tile Size: \n"); + sprintf(cli_buffer," - Samples in 1.D: %27ld\n"\ + " - Samples in 2.D: %27ld\n"\ + " - Samples in 3.D: %27ld\n"\ + " - Samples in 4.D: %27ld\n", header->control.tileSizeX, + header->control.tileSizeY, + header->control.tileSizeZ, + header->control.tileSizeTS); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + strcat(cli_verbose, " __________________________________________________________\n"); + strcat(cli_verbose, "\n"); + strcat(cli_verbose, " 1.D | 2.D | 3.D | 4.D\n"); + sprintf(cli_buffer, " Decomposition Levels: %18d |%4d |%4d |%4d\n", + header->control.decompX, + header->control.decompY, + header->control.decompZ, + header->control.decompTS); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + sprintf(cli_buffer, " Precincts [log2]: %18d |%4d |%4d |%4d\n", + header->control.precSizeX, + header->control.precSizeY, + header->control.precSizeZ, + header->control.precSizeTS); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + sprintf(cli_buffer, " Codeblocks [log2]: %18d |%4d |%4d |%4d\n", + header->control.cbX, + header->control.cbY, + header->control.cbZ, + header->control.cbTS); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + strcat(cli_verbose, " __________________________________________________________\n"); + strcat(cli_verbose, "\n"); + + sprintf(cli_buffer, " Q Number Format: %27d\n", header->control.Qm); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + if (header->control.error_resilience) + { + sprintf(cli_buffer, " Error Resilience: %27s\n", "true"); + } + else + { + sprintf(cli_buffer, " Error Resilience: %27s\n", "false"); + } + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + strcat(cli_verbose, " __________________________________________________________\n"); + strcat(cli_verbose, "\n"); + + for(i = 0; i < header->control.nLayers; ++i) + { + sprintf(cli_buffer, " Quality Layer Nr. %d: %33.2f bpd\n", i, + header->control.bitrate[i]); + strcat(cli_verbose, cli_buffer); + } + + memset(cli_buffer, '0', sizeof(char) * 1024); + strcat(cli_verbose, "\n==============================================================\n"); + printf("%s", cli_verbose); } else { -- 2.45.2 From 742fb3bc786e5ae295d94afaa998d833f416b71d Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Thu, 7 Nov 2024 13:41:38 +0100 Subject: [PATCH 18/21] mse and psnr analysis --- src/tools/bwccmdl.c | 173 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 172 insertions(+), 1 deletion(-) diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index c85ce50..85b139c 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -115,6 +115,14 @@ #define TILES 0x0004 #define USQLY 0x0002 +/*================================================================================================*/ +/** + * @details Macros to determine the minimum or maximum of two values. + */ +/*===========================================================================|====================*/ +#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 + /*================================================================================================*/ /** * @details This macro defines a simple operation to remove a supplied deliminator from a string. @@ -1059,6 +1067,105 @@ parse_opt(int key, return EXIT_SUCCESS; } +static uchar +output_analysis(eas3_data *const ref_data, eas3_data *const org_data) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64_t size; + uint64_t i; + + uint8_t p; + + /*-----------------------*\ + ! DEFINE FLOAT VARIABLES: ! + \*-----------------------*/ + double MSE, PSNR; + double peakVal; + double sum; + + double *dOrig, *dRef; + float *fOrig, *fRef; + + bwc_float minVal, maxVal; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + eas3_param_names *param_name; + + dOrig = org_data->field.d; + dRef = ref_data->field.d; + + fOrig = org_data->field.f; + fRef = ref_data->field.f; + + if(org_data->params.ndim1 == ref_data->params.ndim1 && + org_data->params.ndim2 == ref_data->params.ndim2 && + org_data->params.ndim3 == ref_data->params.ndim3 && + org_data->params.nts == ref_data->params.nts && + org_data->params.npar == ref_data->params.npar) + { + size = (uint64_t)ref_data->params.ndim1 * ref_data->params.ndim2 * + ref_data->params.ndim3 * ref_data->params.nts; + + peakVal = -1.7976931348623157e+308; + PSNR = + MSE = 0; + + if(ref_data->param_names) + { + param_name = ref_data->param_names->root; + p = 0; + while(param_name != NULL) + { + minVal = 1.7976931348623157e+308; + maxVal = -1.7976931348623157e+308; + + if(ref_data->params.accuracy == 2) + { + for(i = 0; i < size; ++i) + { + minVal = MIN(minVal, (double)dRef[i + p * size]); + maxVal = MAX(maxVal, (double)dRef[i + p * size]); + + sum = ((double)dRef[i + p * size] - (double)dOrig[i + p * size]); + + MSE += sum * sum; + } + } + else if(ref_data->params.accuracy == 1) + { + for(i = 0; i < size; ++i) + { + minVal = MIN(minVal, (double)fRef[i + p * size]); + maxVal = MAX(maxVal, (double)fRef[i + p * size]); + + sum = ((double)fRef[i + p * size] - (double)fOrig[i + p * size]); + + MSE += sum * sum; + } + } + peakVal = MAX(peakVal, maxVal - minVal); + param_name = param_name->next; + p++; + } + } + + MSE /= (double)size * ref_data->params.npar; + PSNR = 20 * log10(peakVal/(2 * sqrt(MSE))); + + printf("==============================================================\n"); + printf(" Mean Square Error: %*.2e\n", 22, MSE); + printf(" Peak Signal-to-Noise Ratio: %*.2f\n", 22, PSNR); + printf("==============================================================\n"); + + } + + return EXIT_SUCCESS; +} + /*================================================================================================*/ /** * @details Initialize the argp struct. used to parse the command line arguments @@ -1128,6 +1235,7 @@ int main(int argc, char *argv[]) ! DEFINE STRUCTS: ! \*-----------------------*/ eas3_data *data = NULL; + eas3_data *ref_data = NULL; cli_arguments arguments = {0}; /* Parse the command line arguments and invoke the appro- * @@ -1543,7 +1651,67 @@ int main(int argc, char *argv[]) } else if (arguments.mode == cli_anl) { - printf("Analysis\n"); + /* Ingest the reference data input. */ + if ((ref_data = read_eas3(arguments.ref)) == NULL) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + + /* Ingest the compressed data input. */ + if ((fp = fopen(arguments.in, "r")) == NULL) + { + error_handle = EXIT_FAILURE; + printf(FINERROR); + goto OUT; + } + + root = ftell(fp); + fseek(fp, 0L, SEEK_END); + Lfield = ftell(fp) - root; + fseek(fp, root, SEEK_SET); + + /* Read the compressed data from the input file. */ + input = calloc(Lfield, sizeof(uchar)); + if (fread(input, sizeof(uchar), Lfield, fp) != Lfield) + { + error_handle = EXIT_FAILURE; + printf(RDERROR); + goto OUT; + } + + /* Retrieve header information and allocate output buffer. */ + header = bwc_open_header(input); + size = header->info.nX * header->info.nY * header->info.nZ * + header->info.nTS * header->info.nPar; + if(header->info.data_prec == bwc_precision_double) + { + output = calloc(size, sizeof(double)); + } + else if(header->info.data_prec == bwc_precision_single) + { + output = calloc(size, sizeof(float)); + } + bwc_close_header(header); + + /* Initialize and run the decompression. */ + stream = bwc_init_stream(input, output, comp); + coder = bwc_alloc_decoder(); + if (bwc_create_decompression(coder, stream, 0) == EXIT_FAILURE) + { + error_handle = EXIT_FAILURE; + goto OUT; + } + bwc_decompress(coder, stream); + + /* Parse decompressed data into eas3 data structure * + * and write to the output file. */ + data = calloc(1, sizeof(eas3_data)); + bwc_to_eas3(stream, data); + + output_analysis(ref_data, data); + + goto OUT; } else if (arguments.mode == cli_inf) { @@ -1674,6 +1842,9 @@ OUT: if (data != NULL) eas3_free_data(data); + if (ref_data != NULL) + eas3_free_data(ref_data); + if (stream !=NULL) free(stream); -- 2.45.2 From 64eeda9072d85e236fde950f59ee765dae9a8abf Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Thu, 7 Nov 2024 13:42:16 +0100 Subject: [PATCH 19/21] bug fix; wrong size in memcpy --- src/interfaces/reader/eas3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interfaces/reader/eas3.c b/src/interfaces/reader/eas3.c index f3e2985..4ab8203 100644 --- a/src/interfaces/reader/eas3.c +++ b/src/interfaces/reader/eas3.c @@ -401,13 +401,13 @@ bwc_to_eas3(bwc_stream *const stream, eas3_data *const data) { data->field.d = NULL; data->field.f = calloc(size, sizeof(float)); - memcpy(data->field.f, stream->out, size); + memcpy(data->field.f, stream->out, size*sizeof(float)); } else if(params->accuracy == 2) { data->field.f = NULL; data->field.d = calloc(size, sizeof(double)); - memcpy(data->field.d, stream->out, size); + memcpy(data->field.d, stream->out, size*sizeof(double)); } return 0; -- 2.45.2 From a84768bbec408dea09442487589b41b1eb09b2ce Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Thu, 7 Nov 2024 16:26:20 +0100 Subject: [PATCH 20/21] refactor; print (verbose) header, I/O, and control parameters --- src/tools/bwccmdl.c | 405 +++++++++++++++++--------------------------- 1 file changed, 154 insertions(+), 251 deletions(-) diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index 85b139c..a5bd7b2 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -1067,6 +1067,121 @@ parse_opt(int key, return EXIT_SUCCESS; } +void +printheaderIO(char const *input, char const *output, char const *reference) +{ + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char cli_buffer[1024] = {0}; + char cli_verbose[4096] = {0}; + + strcat(cli_verbose, bwc_header_art); + strcat(cli_verbose, "--------------------------- I/O --------------------------\n\n"); + + sprintf(cli_buffer," Input: %s \n", input); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + sprintf(cli_buffer," Output: %s \n", output); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + sprintf(cli_buffer," Reference: %s \n", reference); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + printf("%s", cli_verbose); +} + +void +printctrl(bwc_gl_ctrl *const control) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint8_t i; + + /*-----------------------*\ + ! DEFINE CHAR VARIABLES: ! + \*-----------------------*/ + char cli_buffer[1024] = {0}; + char cli_verbose[4096] = {0}; + + strcat(cli_verbose, "\n"); + strcat(cli_verbose, "----------------- Compression Parameters -----------------\n"); + strcat(cli_verbose, "\n"); + + strcat(cli_verbose," Tile Size: \n"); + sprintf(cli_buffer," - Samples in 1.D: %27ld\n"\ + " - Samples in 2.D: %27ld\n"\ + " - Samples in 3.D: %27ld\n"\ + " - Samples in 4.D: %27ld\n", control->tileSizeX, + control->tileSizeY, + control->tileSizeZ, + control->tileSizeTS); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + strcat(cli_verbose, " __________________________________________________________\n"); + strcat(cli_verbose, "\n"); + strcat(cli_verbose, " 1.D | 2.D | 3.D | 4.D\n"); + sprintf(cli_buffer, " Decomposition Levels: %18d |%4d |%4d |%4d\n", + control->decompX, + control->decompY, + control->decompZ, + control->decompTS); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + sprintf(cli_buffer, " Precincts [log2]: %18d |%4d |%4d |%4d\n", + control->precSizeX, + control->precSizeY, + control->precSizeZ, + control->precSizeTS); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + sprintf(cli_buffer, " Codeblocks [log2]: %18d |%4d |%4d |%4d\n", + control->cbX, + control->cbY, + control->cbZ, + control->cbTS); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + strcat(cli_verbose, " __________________________________________________________\n"); + strcat(cli_verbose, "\n"); + + sprintf(cli_buffer, " Q Number Format: %27d\n", control->Qm); + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + if (control->error_resilience) + { + sprintf(cli_buffer, " Error Resilience: %27s\n", "true"); + } + else + { + sprintf(cli_buffer, " Error Resilience: %27s\n", "false"); + } + strcat(cli_verbose, cli_buffer); + memset(cli_buffer, '0', sizeof(char) * 1024); + + strcat(cli_verbose, " __________________________________________________________\n"); + strcat(cli_verbose, "\n"); + + for(i = 0; i < control->nLayers; ++i) + { + sprintf(cli_buffer, " Quality Layer Nr. %d: %33.2f bpd\n", i, + control->bitrate[i]); + strcat(cli_verbose, cli_buffer); + } + + memset(cli_buffer, '0', sizeof(char) * 1024); + strcat(cli_verbose, "\n==============================================================\n"); + printf("%s", cli_verbose); +} + static uchar output_analysis(eas3_data *const ref_data, eas3_data *const org_data) { @@ -1209,8 +1324,6 @@ int main(int argc, char *argv[]) ! DEFINE CHAR VARIABLES: ! \*-----------------------*/ char rate[200] = {0}; - char cli_buffer[1024] = {0}; - char cli_verbose[4096] = {0}; char *cli_output = NULL; char *buffer = NULL; @@ -1255,30 +1368,9 @@ int main(int argc, char *argv[]) /* Compress the user supplied data set. */ if (arguments.mode == cli_cmp) { - - /* Ingest the bwccmdl input and set the appropriate cli_ * - * verbose message if the option is set. */ - // TODO: Define a universal data structure and implement a reader - // that ingests different file formats - if ((data = read_eas3(arguments.in)) == NULL) - { - error_handle = EXIT_FAILURE; - goto OUT; - } - if (arguments.verbose == true) - { - strcat(cli_verbose, bwc_header_art); - strcat(cli_verbose, "--------------------------- I/O --------------------------\n\n"); - - sprintf(cli_buffer," Input: %s \n", arguments.in); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); - } - /* Evaluate the appropriate output file. */ if ((arguments.optSet & FLOUT) == 0) arguments.out = arguments.in; - if ((buffer = strrchr(arguments.out, '.')) == NULL) { error_handle = EXIT_FAILURE; @@ -1296,9 +1388,15 @@ int main(int argc, char *argv[]) if (arguments.verbose == true) { - sprintf(cli_buffer," Output: %s \n", cli_output); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); + printheaderIO(arguments.in, cli_output, arguments.ref); + } + + // TODO: Define a universal data structure and implement a reader + // that ingests different file formats + if ((data = read_eas3(arguments.in)) == NULL) + { + error_handle = EXIT_FAILURE; + goto OUT; } /* Evaluate the input and output buffer size and initial- * @@ -1329,15 +1427,6 @@ int main(int argc, char *argv[]) precision); bwc_set_aux(stream, (char*)data->aux.ptr, data->aux.len); - /* Apply the user supplied compression options using the * - * appropriate setter functions. */ - if (arguments.verbose == true) - { - strcat(cli_verbose, "\n"); - strcat(cli_verbose, "----------------- Compression Parameters -----------------\n"); - strcat(cli_verbose, "\n"); - } - if ((arguments.optSet & TILES) != 0) { bwc_set_tiles(coder, arguments.tileSize[0], @@ -1345,20 +1434,6 @@ int main(int argc, char *argv[]) arguments.tileSize[2], arguments.tileSize[3], bwc_tile_sizeof); - if (arguments.verbose == true) - { - strcat(cli_verbose," Tile Size: \n"); - sprintf(cli_buffer," - Samples in 1.D: %27ld\n"\ - " - Samples in 2.D: %27ld\n"\ - " - Samples in 3.D: %27ld\n"\ - " - Samples in 4.D: %27ld\n", arguments.tileSize[0], - arguments.tileSize[1], - arguments.tileSize[2], - arguments.tileSize[3]); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); - delim = true; - } } // TODO: Implement the kernel setter as a global function @@ -1371,35 +1446,12 @@ int main(int argc, char *argv[]) arguments.dwtKernel[3]); }*/ - if ((arguments.verbose == true) && - ((arguments.optSet & (DCLVL | PRECS | CBLKS)) != 0)) - { - if (delim == true) - { - strcat(cli_verbose, " __________________________________________________________\n"); - strcat(cli_verbose, "\n"); - } - strcat(cli_verbose, " 1.D | 2.D | 3.D | 4.D\n"); - delim = true; - } - if ((arguments.optSet & DCLVL) != 0) { bwc_set_decomp(coder, arguments.decompLevel[0], arguments.decompLevel[1], arguments.decompLevel[2], arguments.decompLevel[3]); - - if (arguments.verbose == true) - { - sprintf(cli_buffer, " Decomposition Levels: %18d |%4d |%4d |%4d\n", - arguments.decompLevel[0], - arguments.decompLevel[1], - arguments.decompLevel[2], - arguments.decompLevel[3]); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); - } } if ((arguments.optSet & PRECS) != 0) @@ -1408,17 +1460,6 @@ int main(int argc, char *argv[]) arguments.precSize[1], arguments.precSize[2], arguments.precSize[3]); - - if (arguments.verbose == true) - { - sprintf(cli_buffer, " Precincts [log2]: %18d |%4d |%4d |%4d\n", - arguments.precSize[0], - arguments.precSize[1], - arguments.precSize[2], - arguments.precSize[3]); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); - } } if ((arguments.optSet & CBLKS) != 0) @@ -1427,64 +1468,21 @@ int main(int argc, char *argv[]) arguments.cblkSize[1], arguments.cblkSize[2], arguments.cblkSize[3]); - - if (arguments.verbose == true) - { - sprintf(cli_buffer, " Codeblocks [log2]: %18d |%4d |%4d |%4d\n", - arguments.cblkSize[0], - arguments.cblkSize[1], - arguments.cblkSize[2], - arguments.cblkSize[3]); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); - } - } - - if ((arguments.verbose == true) && - (delim == true) && - (((arguments.optSet & QFRMT) != 0) || arguments.erresilience == true)) - { - - strcat(cli_verbose, " __________________________________________________________\n"); - strcat(cli_verbose, "\n"); } if ((arguments.optSet & QFRMT) != 0) { bwc_set_qm(coder, arguments.Qm); - - if (arguments.verbose == true) - { - sprintf(cli_buffer, " Q Number Format: %27d\n", arguments.Qm); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); - delim = true; - } } if (arguments.erresilience == true) { bwc_set_error_resilience(coder); - if (arguments.verbose == true) - { - sprintf(cli_buffer, " Error Resilience: %27s\n", "true"); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); - delim = true; - } } /* Initialize the rate control string according to the * * specified bit rate/compression ratio. */ - if ((arguments.verbose == true) && - (delim == true)) - { - - strcat(cli_verbose, " __________________________________________________________\n"); - strcat(cli_verbose, "\n"); - } - if ((arguments.optSet & BITRT) != 0) { rtype = 1.0; @@ -1507,32 +1505,21 @@ int main(int argc, char *argv[]) if (arguments.rate[i] > 0) { sprintf(rate + strlen(rate), "%05.3f,", pow(arguments.rate[i]/rtype, exp)); - - if (arguments.verbose == true) - { - sprintf(cli_buffer, " Quality Layer Nr. %d: %33.2f bpd\n", i, - pow(arguments.rate[i]/rtype, exp)); - strcat(cli_verbose, cli_buffer); - } } } rate[strlen(rate) - 1] = '0'; - if (arguments.verbose == true) - { - memset(cli_buffer, '0', sizeof(char) * 1024); - strcat(cli_verbose, "\n==============================================================\n"); - printf("%s", cli_verbose); - } - - /* Initialize the rate control string according to the * - * specified bit rate/compression ratio. */ if (bwc_create_compression(coder, stream, rate) == EXIT_FAILURE) { error_handle = EXIT_FAILURE; goto OUT; } + if(arguments.verbose == true) + { + printctrl(&coder->control); + } + size = bwc_compress(coder, stream); /* Write the codestream to the speicifed file. */ @@ -1553,32 +1540,9 @@ int main(int argc, char *argv[]) } else if (arguments.mode == cli_dcp) { - if ((fp = fopen(arguments.in, "r")) == NULL) - { - error_handle = EXIT_FAILURE; - printf(FINERROR); - goto OUT; - } - - root = ftell(fp); - fseek(fp, 0L, SEEK_END); - Lfield = ftell(fp) - root; - fseek(fp, root, SEEK_SET); - - if (arguments.verbose == true) - { - strcat(cli_verbose, bwc_header_art); - strcat(cli_verbose, "--------------------------- I/O --------------------------\n\n"); - - sprintf(cli_buffer," Input: %s \n", arguments.in); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); - } - /* Evaluate the appropriate output file. */ if ((arguments.optSet & FLOUT) == 0) arguments.out = arguments.in; - if ((buffer = strrchr(arguments.out, '.')) == NULL) { error_handle = EXIT_FAILURE; @@ -1596,18 +1560,21 @@ int main(int argc, char *argv[]) if (arguments.verbose == true) { - sprintf(cli_buffer," Output: %s \n", cli_output); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); + printheaderIO(arguments.in, cli_output, arguments.ref); } - if (arguments.verbose == true) + if ((fp = fopen(arguments.in, "r")) == NULL) { - memset(cli_buffer, '0', sizeof(char) * 1024); - strcat(cli_verbose, "\n==============================================================\n"); - printf("%s", cli_verbose); + error_handle = EXIT_FAILURE; + printf(FINERROR); + goto OUT; } + root = ftell(fp); + fseek(fp, 0L, SEEK_END); + Lfield = ftell(fp) - root; + fseek(fp, root, SEEK_SET); + /* Read the compressed data from the input file. */ input = calloc(Lfield, sizeof(uchar)); if (fread(input, sizeof(uchar), Lfield, fp) != Lfield) @@ -1631,6 +1598,8 @@ int main(int argc, char *argv[]) } bwc_close_header(header); + printctrl(&header->control); + /* Initialize and run the decompression. */ stream = bwc_init_stream(input, output, comp); coder = bwc_alloc_decoder(); @@ -1651,6 +1620,11 @@ int main(int argc, char *argv[]) } else if (arguments.mode == cli_anl) { + if (arguments.verbose == true) + { + printheaderIO(arguments.in, cli_output, arguments.ref); + } + /* Ingest the reference data input. */ if ((ref_data = read_eas3(arguments.ref)) == NULL) { @@ -1694,6 +1668,11 @@ int main(int argc, char *argv[]) } bwc_close_header(header); + if(arguments.verbose == true) + { + printctrl(&header->control); + } + /* Initialize and run the decompression. */ stream = bwc_init_stream(input, output, comp); coder = bwc_alloc_decoder(); @@ -1715,11 +1694,7 @@ int main(int argc, char *argv[]) } else if (arguments.mode == cli_inf) { - strcat(cli_verbose, bwc_header_art); - strcat(cli_verbose, "--------------------------- I/O --------------------------\n\n"); - sprintf(cli_buffer," Input: %s \n", arguments.in); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); + printheaderIO(arguments.in, cli_output, arguments.ref); if ((fp = fopen(arguments.in, "r")) == NULL) { @@ -1742,7 +1717,7 @@ int main(int argc, char *argv[]) goto OUT; } - /* Retrieve header information and allocate output buffer. */ + /* Retrieve header information. */ header = bwc_open_header(input); size = header->info.nX * header->info.nY * header->info.nZ * header->info.nTS * header->info.nPar; @@ -1756,79 +1731,7 @@ int main(int argc, char *argv[]) } bwc_close_header(header); - strcat(cli_verbose, "\n"); - strcat(cli_verbose, "----------------- Compression Parameters -----------------\n"); - strcat(cli_verbose, "\n"); - - strcat(cli_verbose," Tile Size: \n"); - sprintf(cli_buffer," - Samples in 1.D: %27ld\n"\ - " - Samples in 2.D: %27ld\n"\ - " - Samples in 3.D: %27ld\n"\ - " - Samples in 4.D: %27ld\n", header->control.tileSizeX, - header->control.tileSizeY, - header->control.tileSizeZ, - header->control.tileSizeTS); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); - - strcat(cli_verbose, " __________________________________________________________\n"); - strcat(cli_verbose, "\n"); - strcat(cli_verbose, " 1.D | 2.D | 3.D | 4.D\n"); - sprintf(cli_buffer, " Decomposition Levels: %18d |%4d |%4d |%4d\n", - header->control.decompX, - header->control.decompY, - header->control.decompZ, - header->control.decompTS); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); - - sprintf(cli_buffer, " Precincts [log2]: %18d |%4d |%4d |%4d\n", - header->control.precSizeX, - header->control.precSizeY, - header->control.precSizeZ, - header->control.precSizeTS); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); - - sprintf(cli_buffer, " Codeblocks [log2]: %18d |%4d |%4d |%4d\n", - header->control.cbX, - header->control.cbY, - header->control.cbZ, - header->control.cbTS); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); - - strcat(cli_verbose, " __________________________________________________________\n"); - strcat(cli_verbose, "\n"); - - sprintf(cli_buffer, " Q Number Format: %27d\n", header->control.Qm); - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); - - if (header->control.error_resilience) - { - sprintf(cli_buffer, " Error Resilience: %27s\n", "true"); - } - else - { - sprintf(cli_buffer, " Error Resilience: %27s\n", "false"); - } - strcat(cli_verbose, cli_buffer); - memset(cli_buffer, '0', sizeof(char) * 1024); - - strcat(cli_verbose, " __________________________________________________________\n"); - strcat(cli_verbose, "\n"); - - for(i = 0; i < header->control.nLayers; ++i) - { - sprintf(cli_buffer, " Quality Layer Nr. %d: %33.2f bpd\n", i, - header->control.bitrate[i]); - strcat(cli_verbose, cli_buffer); - } - - memset(cli_buffer, '0', sizeof(char) * 1024); - strcat(cli_verbose, "\n==============================================================\n"); - printf("%s", cli_verbose); + printctrl(&header->control); } else { -- 2.45.2 From 3353fd77955f88c1ad423ac12e5d56f07ee4aeb0 Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Thu, 7 Nov 2024 16:26:52 +0100 Subject: [PATCH 21/21] refactor; uchar -> unsigned char --- src/tools/bwccmdl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index a5bd7b2..b6a8d2b 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -1182,7 +1182,7 @@ printctrl(bwc_gl_ctrl *const control) printf("%s", cli_verbose); } -static uchar +static unsigned char output_analysis(eas3_data *const ref_data, eas3_data *const org_data) { /*-----------------------*\ @@ -1531,7 +1531,7 @@ int main(int argc, char *argv[]) goto OUT; } - if (fwrite(stream->out, sizeof(uchar), size, fp) != size) + if (fwrite(stream->out, sizeof(unsigned char), size, fp) != size) { error_handle = EXIT_FAILURE; printf(WRTERROR); @@ -1576,8 +1576,8 @@ int main(int argc, char *argv[]) fseek(fp, root, SEEK_SET); /* Read the compressed data from the input file. */ - input = calloc(Lfield, sizeof(uchar)); - if (fread(input, sizeof(uchar), Lfield, fp) != Lfield) + input = calloc(Lfield, sizeof(unsigned char)); + if (fread(input, sizeof(unsigned char), Lfield, fp) != Lfield) { error_handle = EXIT_FAILURE; printf(RDERROR); @@ -1646,8 +1646,8 @@ int main(int argc, char *argv[]) fseek(fp, root, SEEK_SET); /* Read the compressed data from the input file. */ - input = calloc(Lfield, sizeof(uchar)); - if (fread(input, sizeof(uchar), Lfield, fp) != Lfield) + input = calloc(Lfield, sizeof(unsigned char)); + if (fread(input, sizeof(unsigned char), Lfield, fp) != Lfield) { error_handle = EXIT_FAILURE; printf(RDERROR); @@ -1709,8 +1709,8 @@ int main(int argc, char *argv[]) fseek(fp, root, SEEK_SET); /* Read the compressed data from the input file. */ - input = calloc(Lfield, sizeof(uchar)); - if (fread(input, sizeof(uchar), Lfield, fp) != Lfield) + input = calloc(Lfield, sizeof(unsigned char)); + if (fread(input, sizeof(unsigned char), Lfield, fp) != Lfield) { error_handle = EXIT_FAILURE; printf(RDERROR); -- 2.45.2