From 90645bcf1b10a1554a7b812782f6c2cf9d87536c Mon Sep 17 00:00:00 2001 From: Patrick Vogler Date: Mon, 28 Oct 2024 11:05:34 +0100 Subject: [PATCH] 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; }