diff --git a/include/interfaces/reader/eas3.h b/include/interfaces/reader/eas3.h index 9fe0d20..266d91c 100644 --- a/include/interfaces/reader/eas3.h +++ b/include/interfaces/reader/eas3.h @@ -181,36 +181,6 @@ #define AUX_SIZE 0x8000 - /************************************************************************************************************\ - || ___ _ _ ___ ____ ____ || - || | \_/ |__] |___ [__ || - || | | | |___ ___] || - || || - \************************************************************************************************************/ - /*----------------------------------------------------------------------------------------------*\ - ! ! - ! DESCRIPTION: ! - ! ------------ ! - ! ! - ! This structure is used to read/assemble a packed codestream during coding. The ! - ! byte buffer is flushed to the packed stream as soon as the a single byte has ! - ! been assembled. ! - ! ! - \*----------------------------------------------------------------------------------------------*/ - typedef struct - { - uchar error; // Error flag used during streaming. - - uint64 L; // Number of bytes written to/from stream. - uint64 Lmax; // Size of packed stream. - uint64 size_incr; // Size incrmnt used for stream assembly. - - uint8 T; // Byte buffer. - int8 t; // Byte buffer counter. - - uchar *memory; // Memory handle for packed stream chunck. - } bitstream; - /*----------------------------------------------------------------------------------------------------------*\ ! STRUCT NAME: eas3_header ! ! ----------- ! @@ -303,7 +273,7 @@ { uint64_t file_type; uint64_t accuracy; - uint64_t nzs; + uint64_t nts; uint64_t npar; uint64_t ndim1; uint64_t ndim2; @@ -324,6 +294,52 @@ uint64_t udef_int_size; uint64_t udef_real_size; } eas3_std_params; + + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This structure is used to store field names eas3 file. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct name + { + char name[24]; // Parameter name. + uint8 id; // Parameter index. + + struct name *next; // Next element in linked-list. + struct name *root; // Linked-list root. + } eas3_param_names; + + /*----------------------------------------------------------------------------------------------*\ + ! ! + ! DESCRIPTION: ! + ! ------------ ! + ! ! + ! This structure is used to read eas3 stuff. ! + ! ! + \*----------------------------------------------------------------------------------------------*/ + typedef struct + { + eas3_param_names *param_names; + eas3_std_params params; + + struct field + { + double *d; + float *f; + } field; + + // TODO: implement aux as queue + struct aux + { + uchar *ptr; + uint32 pos; + uint32 len; + } aux; + + } eas3_data; /************************************************************************************************************\ || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || @@ -331,6 +347,21 @@ || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || || || \************************************************************************************************************/ + /*----------------------------------------------------------------------------------------------------------*\ + ! ! + ! 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); + + uchar + bwc_to_eas3(bwc_stream *const stream, eas3_data *const data); + /*----------------------------------------------------------------------------------------------------------*\ ! FUNCTION NAME: bwc_data* read_eas3(const char* const filename) ! ! -------------- ! @@ -342,7 +373,7 @@ ! structure. ! ! ! \*----------------------------------------------------------------------------------------------------------*/ - bwc_data* + eas3_data* read_eas3(char *const filename); /*----------------------------------------------------------------------------------------------------------*\ @@ -356,5 +387,5 @@ ! ! \*----------------------------------------------------------------------------------------------------------*/ uchar - write_eas3(bwc_data *const file, char *const filename); + write_eas3(eas3_data *const file, char *const filename); #endif \ No newline at end of file diff --git a/include/library/private/bitstream.h b/include/library/private/bitstream.h index 6363775..1e8aacc 100755 --- a/include/library/private/bitstream.h +++ b/include/library/private/bitstream.h @@ -92,7 +92,7 @@ \************************************************************************************************/ uint64 bytes_used (bitstream const *const stream); //==========|==========================|======================|======|======|===================== - bitstream* init_stream (uchar *const memory, + bitstream* init_bitstream (uchar *const memory, uint32 const size, char const instr); //==========|==========================|======================|======|======|===================== @@ -117,8 +117,10 @@ //==========|==========================|======================|======|======|===================== uchar get_bit (bitstream *const stream); //==========|==========================|======================|======|======|===================== - uchar terminate_stream (bitstream *stream, - bwc_stream *const packed_stream); + uchar shrink_to_fit (bitstream *const stream); //==========|==========================|======================|======|======|===================== - void release_packed_stream (bwc_stream *const stream); + uchar transfer_to_span (bitstream *const stream, + bwc_span *const span); + //==========|==========================|======================|======|======|===================== + void release_packed_stream (bwc_span *const stream); #endif diff --git a/include/library/private/codestream.h b/include/library/private/codestream.h index 482b8eb..2e022aa 100755 --- a/include/library/private/codestream.h +++ b/include/library/private/codestream.h @@ -89,16 +89,22 @@ || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || || || \************************************************************************************************/ - uchar assemble_main_header (bwc_field *const field); + uchar assemble_main_header (bwc_codec *const codec); //==========|==========================|======================|======|======|===================== - uchar codestream_write_aux (bwc_stream *const header, - bwc_stream *const aux); + uchar codestream_write_aux (bwc_span *const header, + bwc_span *const aux); //==========|==========================|======================|======|======|===================== - uchar codestream_write_com (bwc_stream *const header, - bwc_stream *const com); + uchar codestream_write_com (bwc_span *const header, + bwc_span *const com); //==========|==========================|======================|======|======|===================== - bwc_stream* assemble_codestream (bwc_field *const field); + size_t assemble_codestream (bwc_codec *const codec, + bwc_stream *const stream); //==========|==========================|======================|======|======|===================== - bwc_field* parse_codestream (bwc_data *const data, + 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); #endif \ No newline at end of file diff --git a/include/library/private/constants.h b/include/library/private/constants.h index c8af8d0..1251b4e 100755 --- a/include/library/private/constants.h +++ b/include/library/private/constants.h @@ -114,8 +114,14 @@ \*----------------------------------------------------------------------------------------------*/ typedef enum { - bwc_type_half, - bwc_type_single, - bwc_type_double, - } bwc_type; + bwc_precision_half = 2, + bwc_precision_single = 4, + bwc_precision_double = 8, + } bwc_precision; + + typedef enum + { + comp, + decomp, + } bwc_mode; #endif \ No newline at end of file diff --git a/include/library/private/dwt.h b/include/library/private/dwt.h index d9fa0eb..1b17a6f 100755 --- a/include/library/private/dwt.h +++ b/include/library/private/dwt.h @@ -157,13 +157,13 @@ \************************************************************************************************/ uchar initialize_gain_lut (); //==========|==========================|======================|======|=======|==================== - bwc_float get_dwt_energy_gain (bwc_field *const field, + bwc_float get_dwt_energy_gain (bwc_codec *const codec, uchar const highband_flag, uint16 const level); //==========|==========================|======================|======|=======|==================== - uchar forward_wavelet_transform (bwc_field *const field, + uchar forward_wavelet_transform (bwc_codec *const codec, bwc_parameter *const parameter); //==========|==========================|======================|======|=======|==================== - uchar inverse_wavelet_transform (bwc_field *const field, + uchar inverse_wavelet_transform (bwc_codec *const codec, bwc_parameter *const parameter); #endif \ No newline at end of file diff --git a/include/library/private/libbwc.h b/include/library/private/libbwc.h index 8418632..1afab38 100755 --- a/include/library/private/libbwc.h +++ b/include/library/private/libbwc.h @@ -64,92 +64,99 @@ || || \************************************************************************************************/ //==========|==========================|======================|======|=======|==================== - bwc_data* bwc_initialize_data (double *const field, - uint64 const nX, - uint64 const nY, - uint64 const nZ, - uint16 const nTS, - uint8 const nPar, - char *const file_extension); + bwc_stream* bwc_init_stream (void *const inpbuf, + void *const outbuf, + bwc_mode const mode); //==========|==========================|======================|======|=======|==================== - uchar bwc_set_com (bwc_data *const data, + uchar bwc_set_com (bwc_stream *const stream, char const *const com, uint16 const size); //==========|==========================|======================|======|=======|==================== - uchar bwc_set_aux (bwc_data *const data, + uchar bwc_set_aux (bwc_stream *const stream, char const *const aux, uint32 const size); //==========|==========================|======================|======|=======|==================== - void bwc_add_param (bwc_data *const data, - char *const name, - uint8 const precision); + uchar create_codec (bwc_codec *const codec); //==========|==========================|======================|======|=======|==================== - void bwc_get_data (bwc_data *const data, - uchar *const buffer, - uint64 const size); + bwc_codec* configure_codec (bwc_codec *const codec, + uint64 const nX, + uint64 const nY, + uint64 const nZ, + uint64 const nTS, + uint8 const nPar, + bwc_precision const prec); //==========|==========================|======================|======|=======|==================== - void bwc_free_data (bwc_data *const data); + bwc_codec* bwc_alloc_coder (uint64 const nX, + uint64 const nY, + uint64 const nZ, + uint64 const nTS, + uint8 const nPar, + bwc_precision const prec); //==========|==========================|======================|======|=======|==================== - uchar create_field (bwc_field *const field); + bwc_codec* bwc_alloc_decoder (); //==========|==========================|======================|======|=======|==================== - void bwc_kill_compression (bwc_field *const field); + void bwc_free_codec (bwc_codec *const codec); //==========|==========================|======================|======|=======|==================== - bwc_field* bwc_initialize_field (bwc_data *const data); + void bwc_set_error_resilience (bwc_codec *const codec); //==========|==========================|======================|======|=======|==================== - void bwc_set_error_resilience (bwc_field *const field); - //==========|==========================|======================|======|=======|==================== - void set_quant_style (bwc_field *const field, + void set_quant_style (bwc_codec *const codec, bwc_quant_st const quantization_style); //==========|==========================|======================|======|=======|==================== - void set_quant_step_size (bwc_field *const field, + void set_quant_step_size (bwc_codec *const codec, double const delta); //==========|==========================|======================|======|=======|==================== - void set_progression (bwc_field *const field, + void set_progression (bwc_codec *const codec, bwc_prog_ord const progression); //==========|==========================|======================|======|=======|==================== - void set_kernels (bwc_field *const field, + void set_kernels (bwc_codec *const codec, bwc_dwt_filter const KernelX, bwc_dwt_filter const KernelY, bwc_dwt_filter const KernelZ, bwc_dwt_filter const KernelTS); //==========|==========================|======================|======|=======|==================== - void bwc_set_decomp (bwc_field *const field, + void bwc_set_decomp (bwc_codec *const codec, uint8 const decompX, uint8 const decompY, uint8 const decompZ, uint8 const decompTS); //==========|==========================|======================|======|=======|==================== - void bwc_set_precincts (bwc_field *const field, + void bwc_set_precincts (bwc_codec *const codec, uint8 const pX, uint8 const pY, uint8 const pZ, uint8 const pTS); //==========|==========================|======================|======|=======|==================== - void bwc_set_codeblocks (bwc_field *const field, + void bwc_set_codeblocks (bwc_codec *const codec, uint8 const cbX, uint8 const cbY, uint8 const cbZ, uint8 const cbTS); //==========|==========================|======================|======|=======|==================== - void bwc_set_qm (bwc_field *const field, + void bwc_set_qm (bwc_codec *const codec, uint8 const Qm); //==========|==========================|======================|======|=======|==================== - void bwc_set_tiles (bwc_field *const field, + void bwc_set_tiles (bwc_codec *const codec, uint64 const tilesX, uint64 const tilesY, uint64 const tilesZ, uint64 const tilesTS, bwc_tile_instr const instr); //==========|==========================|======================|======|=======|==================== - uchar bwc_create_compression (bwc_field *const field, + 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); //==========|==========================|======================|======|=======|==================== - uchar bwc_compress (bwc_field *const field, - bwc_data *const data); + size_t bwc_compress (bwc_codec *const codec, + bwc_stream *const data); //==========|==========================|======================|======|=======|==================== - bwc_field* bwc_create_decompression (bwc_data *const data, + uchar bwc_create_decompression (bwc_codec *const codec, + bwc_stream *const stream, uint8 const layer); //==========|==========================|======================|======|=======|==================== - uchar bwc_decompress (bwc_field *const field, - bwc_data *const data); -#endif \ No newline at end of file + uchar bwc_decompress (bwc_codec *const codec, + bwc_stream *const stream); +#endif diff --git a/include/library/private/tier1.h b/include/library/private/tier1.h index 13f60eb..14546cc 100755 --- a/include/library/private/tier1.h +++ b/include/library/private/tier1.h @@ -16,7 +16,7 @@ || ------------ || || || || This file describes a set of functions that can be used to de-/encode bwc || -|| codeblocks described by the bwc_field structure according to the embedded block || +|| codeblocks described by the bwc_codec structure according to the embedded block || || coding paradigm described by the JPEG 2000 standard. For more information please || || refere to JPEG2000 by D. S. Taubman and M. W. Marcellin. || || || @@ -156,11 +156,11 @@ || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || || || \************************************************************************************************/ - uchar t1_encode (bwc_field *const field, + uchar t1_encode (bwc_codec *const codec, bwc_tile *const tile, bwc_parameter *const parameter); //==========|==========================|======================|======|=======|==================== - uchar t1_decode (bwc_field *const field, + uchar t1_decode (bwc_codec *const codec, bwc_tile *const tile, bwc_parameter *const parameter); diff --git a/include/library/private/tier2.h b/include/library/private/tier2.h index 3dc0bb2..d55cb65 100755 --- a/include/library/private/tier2.h +++ b/include/library/private/tier2.h @@ -16,7 +16,7 @@ || ------------ || || || || This file describes a set of functions that can be used to de-/encode bwc || -|| codeblocks described by the bwc_field structure according to the embedded block || +|| codeblocks described by the bwc_codec structure according to the embedded block || || coding paradigm described by the JPEG 2000 standard. For more information please || || refere to JPEG2000 by D. S. Taubman and M. W. Marcellin. || || || @@ -76,10 +76,10 @@ || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || || || \************************************************************************************************/ - uchar t2_encode (bwc_field *const field, + uchar t2_encode (bwc_codec *const codec, bwc_tile *const tile); //==========|==========================|======================|======|=======|==================== - uchar parse_packet (bwc_field *const field, + uchar parse_packet (bwc_codec *const codec, bwc_tile *const tile, bwc_packet *const packet, uint64 const body_size); diff --git a/include/library/private/types.h b/include/library/private/types.h index 323101f..06b49b6 100755 --- a/include/library/private/types.h +++ b/include/library/private/types.h @@ -99,7 +99,7 @@ uchar *access; // Pointer used to parse packed stream. uchar *memory; // Memory handle for the packed stream. - } bwc_stream; + } bwc_span; /*----------------------------------------------------------------------------------------------*\ ! ! @@ -138,29 +138,6 @@ bwc_tagtree_node *nodes; // Pointer to the tagtree nodes. } bwc_tagtree; - - /*----------------------------------------------------------------------------------------------*\ - ! ! - ! DESCRIPTION: ! - ! ------------ ! - ! ! - ! This structure defines a linked list which stores the size, index, and bit pre- ! - ! cision The string name is used to store the parameter name supplied by the ! - ! function caller. ! - ! ! - \*----------------------------------------------------------------------------------------------*/ - typedef struct opt - { - char name[24]; // Parameter name. - uint8 id; // Parameter index. - - uint64 size; // Parameter size after sub-sampling. - uint8 precision; // Parameter precision. - - struct opt *next; // Next element in linked-list. - struct opt *root; // Linked-list root. - } bwc_cmd_opts_ll; - /*----------------------------------------------------------------------------------------------*\ ! ! ! DESCRIPTION: ! @@ -178,12 +155,8 @@ uint8 nPar; // Number of parameters. - uint8 precision; // Flag defining codec precision. - - uint8 codec_prec; // Encoder/decoder bit precision. - char f_ext[20]; // Uncompressed data set file extension. - - bwc_cmd_opts_ll *parameter; // Command options linked-list. + bwc_precision data_prec; // Data type of uncompressed field data. + bwc_precision codec_prec; // Encoder/decoder bit precision. } bwc_gl_inf; /*----------------------------------------------------------------------------------------------*\ @@ -197,22 +170,17 @@ \*----------------------------------------------------------------------------------------------*/ typedef struct { - bwc_gl_inf info; // Gloabal info structure. - FILE *fp; // File point to (un)compr. data-set. - struct codestream { - bwc_stream *data; // Data codestream block. - bwc_stream *aux; // Auxiliary info. codestream block. - bwc_stream *com; // Comment codestream block. + bwc_span *aux; // Auxiliary info. codestream block. + bwc_span *com; // Comment codestream block. }codestream; - struct field - { - double *d; // Double precision numerical data-set. - float *f; // Single precision numerical data-set. - }field; - } bwc_data; + void *inp; // User managed buffer for input + void *out; // User managed buffer for output + + bwc_mode mode; // Flag to signal (de-)compression + } bwc_stream; /*----------------------------------------------------------------------------------------------*\ ! ! @@ -420,8 +388,8 @@ \*----------------------------------------------------------------------------------------------*/ typedef struct { - bwc_stream header; // Packed stream header. - bwc_stream body; // Packed stream body. + bwc_span header; // Packed stream header. + bwc_span body; // Packed stream body. uint8 e; // Indicator for packet cb. contributions. uint32 size; // Codestream packet size. @@ -528,14 +496,9 @@ \*----------------------------------------------------------------------------------------------*/ typedef struct { - uint64 size; // Parameter size. - char *name; // Parameter name. - uint64 X0, Y0, Z0, TS0; // Tile parameter starting point. uint64 X1, Y1, Z1, TS1; // Tile parameter end point. - uint8 precision; // Tile parameter precision. - bwc_float parameter_min; // Min. value of tile parameter. bwc_float parameter_max; // Max. value of tile parameter. } bwc_param_inf; @@ -696,26 +659,32 @@ bwc_prog_ord progression; // Packet progression order. } bwc_gl_ctrl; - /*----------------------------------------------------------------------------------------------*\ - ! ! - ! 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 that is used to probe header information from a compressed data set. + */ +/*================================================================================================*/ typedef struct { - bwc_gl_inf *info; // Gloabal info structure + 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; + +/*================================================================================================*/ +/** + * @details Structure holding all the necessary parameters defining and controlling a bwc + * (de-)compression run. + */ +/*================================================================================================*/ + typedef struct + { + bwc_gl_inf info; // Global info structure bwc_gl_ctrl control; // Global control structure bwc_tile *tile; // Structure defining bwc tile. - bwc_stream *aux; // Auxiliary info. codestream block. - bwc_stream *com; // Comment codestream block. - } bwc_field; + bwc_mode mode; // Flag to signal (de-)compression + } bwc_codec; #endif \ No newline at end of file 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/interfaces/fortran/bwc.F90 b/src/interfaces/fortran/bwc.F90 index b71e98a..dae5ec8 100644 --- a/src/interfaces/fortran/bwc.F90 +++ b/src/interfaces/fortran/bwc.F90 @@ -48,10 +48,10 @@ module bwc !| | | \| |___ |___ |__| |__/ |___ |! !| |! !************************************************************************************************! - use, intrinsic :: iso_c_binding, only: C_PTR, C_INT64_T, C_INT32_T, C_INT16_T, C_INT8_T, & - C_INT, C_DOUBLE, C_CHAR, C_SIGNED_CHAR - IMPLICIT NONE - PRIVATE + use, intrinsic :: iso_c_binding, only: c_ptr, c_int64_t, c_int32_t, c_int16_t, c_int8_t, & + c_int, c_double, c_char, c_signed_char + implicit none + private !************************************************************************************************! !| ____ ____ _ _ ____ ___ ____ _ _ ___ ____ |! @@ -59,25 +59,25 @@ module bwc !| |___ |__| | \| ___] | | | | \| | ___] |! !| |! !************************************************************************************************! - ENUM, BIND(C) + enum, bind(c) enumerator :: bwc_dwt_9_7 = 0, & bwc_dwt_5_3 = 1, & bwc_dwt_haar = 2 - END ENUM + end enum !*==============================================================================================*! - ENUM, BIND(C) - enumerator :: bwc_prog_LRCP = 0 - END ENUM + enum, bind(c) + enumerator :: bwc_prog_lrcp = 0 + end enum !*==============================================================================================*! - ENUM, BIND(C) + enum, bind(c) enumerator :: bwc_qt_none = 0, & bwc_qt_derived = 1 - END ENUM + end enum !*==============================================================================================*! - ENUM, BIND(C) + enum, bind(c) enumerator :: bwc_tile_sizeof = 0, & bwc_tile_numbof = 1 - END ENUM + end enum !************************************************************************************************! !| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ |! @@ -86,294 +86,113 @@ module bwc !| |! !************************************************************************************************! interface - function initialize_data_f(field, nX, nY, nZ, nTS, nPar, file_extension) result(data) & - BIND(C, NAME="bwc_initialize_data") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field - TYPE(C_PTR) :: data - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT16_T), VALUE :: nX, nY, nZ - INTEGER(KIND=C_INT8_T), VALUE :: nTS, nPar - - !*-----------------------*! - ! DEFINE CHAR VARIABLES: ! - !*-----------------------*! - CHARACTER(KIND=C_CHAR) :: file_extension(*) - end function initialize_data_f + function init_stream_f(inpbuf, outbuf, mode) result(stream) & + bind(c, name="bwc_init_stream") + import + type(c_ptr) :: stream + type(c_ptr), value :: inpbuf + type(c_ptr), value :: outbuf + integer(kind=c_int), value :: mode + end function init_stream_f !*============================================================================================*! - subroutine add_param_f(data, name, sample, dim, precision) & - BIND(C, NAME="bwc_add_param") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: data - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT16_T), VALUE :: sample - INTEGER(KIND=C_INT8_T), VALUE :: precision - INTEGER(KIND=C_SIGNED_CHAR), VALUE :: dim - - !*-----------------------*! - ! DEFINE CHAR VARIABLES: ! - !*-----------------------*! - CHARACTER(KIND=C_CHAR) :: name(*) - end subroutine add_param_f + function alloc_coder_f(nx, ny, nz, nts, npar, prec) result(codec) & + bind(c, name="bwc_alloc_coder") + import + type(c_ptr) :: codec + integer(kind=c_int64_t), value :: nx, ny, nz, nts + integer(kind=c_int8_t), value :: npar + integer(kind=c_int), value :: prec + end function alloc_coder_f !*============================================================================================*! - subroutine get_data_f(data, buffer, size) & - BIND(C, NAME="bwc_get_data") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: data - TYPE(C_PTR), VALUE :: buffer - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT64_T), Value :: size - end subroutine get_data_f + function alloc_decoder_f() result(codec) & + bind(c, name="bwc_alloc_decoder") + import + type(c_ptr) :: codec + end function alloc_decoder_f !*============================================================================================*! - subroutine free_data_f(data) & - BIND(C, NAME="bwc_free_data") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: data - end subroutine free_data_f + subroutine free_codec_f(codec) & + bind(c, name="bwc_free_codec") + import + type(c_ptr), value :: codec + end subroutine free_codec_f !*============================================================================================*! - subroutine kill_compression_f(field) & - BIND(C, NAME="bwc_kill_compression") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field - end subroutine kill_compression_f - !*============================================================================================*! - function initialize_field_f(data) result(field) & - BIND(C, NAME="bwc_initialize_field") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: data - TYPE(C_PTR) :: field - end function initialize_field_f - !*============================================================================================*! - subroutine set_error_resilience_f(field) & - BIND(C, NAME="bwc_set_error_resilience") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field + subroutine set_error_resilience_f(codec) & + bind(c, name="bwc_set_error_resilience") + import + type(c_ptr), value :: codec end subroutine set_error_resilience_f !*============================================================================================*! - subroutine set_quantization_style_f(field, quantization_style) & - BIND(C, NAME="bwc_set_quantization_style") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT), VALUE :: quantization_style - end subroutine set_quantization_style_f - !*============================================================================================*! - subroutine set_quantization_step_size_f(field, delta) & - BIND(C, NAME="bwc_set_quantization_step_size") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field - - !*-----------------------*! - ! DEFINE FLOAT VARIABLES: ! - !*-----------------------*! - REAL(KIND=C_DOUBLE), VALUE :: delta - end subroutine set_quantization_step_size_f - !*============================================================================================*! - subroutine set_progression_f(field, progression) & - BIND(C, NAME="bwc_set_progression") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT), VALUE :: progression - end subroutine set_progression_f - !*============================================================================================*! - subroutine set_kernels_f(field, KernelX, KernelY, KernelZ, KernelTS) & - BIND(C, NAME="bwc_set_kernels") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT), VALUE :: KernelX, KernelY - INTEGER(KIND=C_INT), VALUE :: KernelZ, KernelTS - end subroutine set_kernels_f - !*============================================================================================*! - subroutine set_decomp_f(field, decompX, decompY, decompZ, decompTS) & - BIND(C, NAME="bwc_set_decomp") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT8_T), VALUE :: decompX, decompY - INTEGER(KIND=C_INT8_T), VALUE :: decompZ, decompTS + subroutine set_decomp_f(codec, decompx, decompy, decompz, decompts) & + bind(c, name="bwc_set_decomp") + import + type(c_ptr), value :: codec + integer(kind=c_int8_t), value :: decompx, decompy + integer(kind=c_int8_t), value :: decompz, decompts end subroutine set_decomp_f !*============================================================================================*! - subroutine set_precincts_f(field, pX, pY, pZ, pTS) & - BIND(C, NAME="bwc_set_precincts") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT8_T), VALUE :: pX, pY - INTEGER(KIND=C_INT8_T), VALUE :: pZ, pTS + subroutine set_precincts_f(codec, px, py, pz, pts) & + bind(c, name="bwc_set_precincts") + import + type(c_ptr), value :: codec + integer(kind=c_int8_t), value :: px, py + integer(kind=c_int8_t), value :: pz, pts end subroutine set_precincts_f !*============================================================================================*! - subroutine set_codeblocks_f(field, cbX, cbY, cbZ, cbTS) & - BIND(C, NAME="bwc_set_codeblocks") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT8_T), VALUE :: cbX, cbY - INTEGER(KIND=C_INT8_T), VALUE :: cbZ, cbTS + subroutine set_codeblocks_f(codec, cbx, cby, cbz, cbts) & + bind(c, name="bwc_set_codeblocks") + import + type(c_ptr), value :: codec + integer(kind=c_int8_t), value :: cbx, cby + integer(kind=c_int8_t), value :: cbz, cbts end subroutine set_codeblocks_f !*============================================================================================*! - subroutine set_qm_f(field, Qm) & - BIND(C, NAME="bwc_set_qm") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT8_T), VALUE :: Qm + subroutine set_qm_f(codec, qm) & + bind(c, name="bwc_set_qm") + import + type(c_ptr), value :: codec + integer(kind=c_int8_t), value :: qm end subroutine set_qm_f !*============================================================================================*! - subroutine set_tiles_f(field, tilesX, tilesY, tilesZ, tilesTS, instr) & - BIND(C, NAME="bwc_set_tiles") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT64_T), VALUE :: tilesX, tilesY, tilesZ - INTEGER(KIND=C_INT16_T), VALUE :: tilesTS - INTEGER(KIND=C_INT), VALUE :: instr + subroutine set_tiles_f(codec, tilesx, tilesy, tilesz, tilests, instr) & + bind(c, name="bwc_set_tiles") + import + type(c_ptr), value :: codec + integer(kind=c_int64_t), value :: tilesx, tilesy, tilesz, tilests + integer(kind=c_int), value :: instr end subroutine set_tiles_f !*============================================================================================*! - function create_compression_f(field, rate_control) result(error_flag) & - BIND(C, NAME="bwc_create_compression") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT8_T) :: error_flag - - !*-----------------------*! - ! DEFINE CHAR VARIABLES: ! - !*-----------------------*! - CHARACTER(KIND=C_CHAR) :: rate_control(*) + function create_compression_f(codec, stream, rate_control) result(error_flag) & + bind(c, name="bwc_create_compression") + import + integer(kind=c_int8_t) :: error_flag + type(c_ptr), value :: codec + type(c_ptr), value :: stream + character(kind=c_char) :: rate_control(*) end function create_compression_f !*============================================================================================*! - function compress_f(field, data) result(error_flag) & - BIND(C, NAME="bwc_compress") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field - TYPE(C_PTR), VALUE :: data - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT8_T) :: error_flag + function compress_f(codec, stream) result(error_flag) & + bind(c, name="bwc_compress") + import + integer(kind=c_int8_t) :: error_flag + type(c_ptr), value :: codec + type(c_ptr), value :: stream end function compress_f !*============================================================================================*! - function create_decompression_f(data, layer) result(field) & - BIND(C, NAME="bwc_create_decompression") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR) :: field - TYPE(C_PTR), VALUE :: data - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT8_T), VALUE :: layer + function create_decompression_f(codec, stream, layer) result(error_flag) & + bind(c, name="bwc_create_decompression") + import + integer(kind=c_int8_t) :: error_flag + type(c_ptr), value :: codec + type(c_ptr), value :: stream + integer(kind=c_int8_t), value :: layer end function create_decompression_f !*============================================================================================*! - function decompress_f(field, data) result(error_flag) & - BIND(C, NAME="bwc_decompress") - IMPORT - !*-----------------------*! - ! DEFINE POINTERS: ! - !*-----------------------*! - TYPE(C_PTR), VALUE :: field - TYPE(C_PTR), VALUE :: data - - !*-----------------------*! - ! DEFINE INT VARIABLES: ! - !*-----------------------*! - INTEGER(KIND=C_INT8_T) :: error_flag + function decompress_f(codec, stream) result(error_flag) & + bind(c, name="bwc_decompress") + import + integer(kind=c_int8_t) :: error_flag + type(c_ptr), value :: codec + type(c_ptr), value :: stream end function decompress_f end interface @@ -395,24 +214,17 @@ module bwc public :: bwc_tile_sizeof, & bwc_tile_numbof - public :: bwc_initialize_data, & - bwc_get_data, & - bwc_free_data - - public :: bwc_initialize_field, & - bwc_add_param, & - bwc_kill_compression + public :: bwc_init_stream, & + bwc_alloc_coder, & + bwc_alloc_decoder, & + bwc_free_codec public :: bwc_set_error_resilience, & - bwc_set_quantization_style, & - bwc_set_quantization_step_size, & - bwc_set_progression, & - bwc_set_kernels, & bwc_set_decomp, & bwc_set_precincts, & bwc_set_codeblocks, & bwc_set_qm, & - bwc_set_tiles, + bwc_set_tiles public :: bwc_create_compression, & bwc_compress, & diff --git a/src/interfaces/python/bwc.py b/src/interfaces/python/bwc.py index e45984e..c3e7189 100644 --- a/src/interfaces/python/bwc.py +++ b/src/interfaces/python/bwc.py @@ -84,55 +84,37 @@ const = _const() #| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] |# #| |# #**************************************************************************************************# -def free_data(data): - fun = libbwc.bwc_free_data - fun.restype = None - fun.argtypes = [ctypes.c_void_p] - fun(data) -#==================================================================================================# -def initialize_data(data, nX, nY, nZ, nTS, nPar, file_extension): - fun = libbwc.bwc_initialize_data +def init_stream(inpbuf, outbuf, mode): + fun = libbwc.bwc_init_stream fun.restype = ctypes.c_void_p fun.argtypes = [ndpointer(ctypes.c_double, flags="C_CONTIGUOUS"), + ndpointer(ctypes.c_double, flags="C_CONTIGUOUS"), + ctypes.c_char_p] + return ctypes.c_void_p(fun(inpbuf, outbuf, mode.encode('utf-8'))) +#==================================================================================================# +def alloc_coder(nX, nY, nZ, nTS, nPar, prec): + fun = libbwc.bwc_alloc_coder + fun.restype = ctypes.c_void_p + fun.argtypes = [ctypes.c_uint64, ctypes.c_uint64, ctypes.c_uint64, - ctypes.c_uint64, - ctypes.c_uint16, ctypes.c_uint8, ctypes.c_char_p] - return ctypes.c_void_p(fun(data, nX, nY, nZ, nTS, nPar, file_extension.encode('utf-8'))) + return ctypes.c_void_p(fun(nX, nY, nZ, nTS, nPar, prec.encode('utf-8'))) #==================================================================================================# -def get_data(data, buffer, size): - fun = libbwc.bwc_get_data - fun.restype = None - fun.argtypes = [ctypes.c_void_p, - ndpointer(ctypes.c_double, flags="C_CONTIGUOUS"), - ctypes.c_uint64] - fun(data, buffer, size) -#==================================================================================================# -def add_param(data, name, sample, dim, precision): - fun = libbwc.bwc_add_param - fun.restype = None - fun.argtypes = [ctypes.c_void_p, - ctypes.c_char_p, - ctypes.c_uint16, - ctypes.c_uint8, - ctypes.c_uint8] - fun(data, name.encode('utf-8'), sample, dim, precision) -#==================================================================================================# -def kill_compression(field): - fun = libbwc.bwc_kill_compression - fun.restype = None - fun.argtypes = [ctypes.c_void_p] - fun(field) -#==================================================================================================# -def initialize_field(data): - fun = libbwc.bwc_initialize_field +def alloc_decoder(): + fun = libbwc.bwc_alloc_decoder fun.restype = ctypes.c_void_p - fun.argtypes = [ctypes.c_void_p] - return ctypes.c_void_p(fun(data)) + fun.argtypes = [] + return ctypes.c_void_p(fun()) #==================================================================================================# -def set_codeblocks(field, cbX, cbY, cbZ, cbTS): +def free_codec(codec): + fun = libbwc.bwc_free_codec + fun.restype = None + fun.argtypes = [ctypes.c_void_p] + fun(codec) +#==================================================================================================# +def set_codeblocks(codec, cbX, cbY, cbZ, cbTS): fun = libbwc.bwc_set_codeblocks fun.restype = None fun.argtypes = [ctypes.c_void_p, @@ -140,9 +122,9 @@ def set_codeblocks(field, cbX, cbY, cbZ, cbTS): ctypes.c_uint8, ctypes.c_uint8, ctypes.c_uint8] - fun(field, cbX, cbY, cbZ, cbTS) + fun(codec, cbX, cbY, cbZ, cbTS) #==================================================================================================# -def set_decomp(field, decompX, decompY, decompZ, decompTS): +def set_decomp(codec, decompX, decompY, decompZ, decompTS): fun = libbwc.bwc_set_decomp fun.restype = None fun.argtypes = [ctypes.c_void_p, @@ -150,16 +132,16 @@ def set_decomp(field, decompX, decompY, decompZ, decompTS): ctypes.c_uint8, ctypes.c_uint8, ctypes.c_uint8] - fun(field, decompX, decompY, decompZ, decompTS) + fun(codec, decompX, decompY, decompZ, decompTS) #==================================================================================================# -def set_qm(field, Qm): +def set_qm(codec, Qm): fun = libbwc.bwc_set_qm fun.restype = None fun.argtypes = [ctypes.c_void_p, - ctypes.c_int8] - fun(field, Qm) + ctypes.c_uint8] + fun(codec, Qm) #==================================================================================================# -def set_tiles(field, tilesX, tilesY, tilesZ, tilesTS, instr): +def set_tiles(codec, tilesX, tilesY, tilesZ, tilesTS, instr): fun = libbwc.bwc_set_tiles fun.restype = None fun.argtypes = [ctypes.c_void_p, @@ -168,9 +150,9 @@ def set_tiles(field, tilesX, tilesY, tilesZ, tilesTS, instr): ctypes.c_uint64, ctypes.c_uint64, ctypes.c_char_p] - fun(field, tilesX, tilesY, tilesZ, tilesTS, instr.encode('utf-8')) + fun(codec, tilesX, tilesY, tilesZ, tilesTS, instr.encode('utf-8')) #==================================================================================================# -def set_precincts(field, pX, pY, pZ, pTS): +def set_precincts(codec, pX, pY, pZ, pTS): fun = libbwc.bwc_set_precincts fun.restype = None fun.argtypes = [ctypes.c_void_p, @@ -178,32 +160,34 @@ def set_precincts(field, pX, pY, pZ, pTS): ctypes.c_uint8, ctypes.c_uint8, ctypes.c_uint8] - fun(field, pX, pY, pZ, pTS) + fun(codec, pX, pY, pZ, pTS) #==================================================================================================# -def create_compression(field, rate_control): +def create_compression(codec, stream, rate_control): fun = libbwc.bwc_create_compression - fun.restype = None + fun.restype = ctypes.c_uchar fun.argtypes = [ctypes.c_void_p, + ctypes.c_void_p, ctypes.c_char_p] - fun(field, rate_control.encode('utf-8')) + return ctypes.c_uchar(fun(codec, stream, rate_control.encode('utf-8'))) #==================================================================================================# -def compress(field, data): +def compress(codec, stream): fun = libbwc.bwc_compress - fun.restype = None + fun.restype = ctypes.c_size_t fun.argtypes = [ctypes.c_void_p, ctypes.c_void_p] - fun(field, data) + return ctypes.c_size_t(fun(codec, stream)) #==================================================================================================# -def create_decompression(field, data): +def create_decompression(codec, stream, layer): fun = libbwc.bwc_create_decompression - fun.restype = ctypes.c_void_p + fun.restype = ctypes.c_uchar fun.argtypes = [ctypes.c_void_p, + ctypes.c_void_p, ctypes.c_uint8] - return ctypes.c_void_p(fun(field, data)) + return ctypes.c_uchar(fun(codec, stream, layer)) #==================================================================================================# -def decompress(field, data): +def decompress(codec, stream): fun = libbwc.bwc_decompress - fun.restype = None + fun.restype = ctypes.c_uchar fun.argtypes = [ctypes.c_void_p, ctypes.c_void_p] - fun(field, data) \ No newline at end of file + return ctypes.c_uchar(fun(codec, stream)) \ No newline at end of file diff --git a/src/interfaces/reader/eas3.c b/src/interfaces/reader/eas3.c index 2631bd9..4ab8203 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" /************************************************************************************************************\ || ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || @@ -84,454 +102,48 @@ || | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || || || \************************************************************************************************************/ -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uint32 bytes_used(bitstream *const stream) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function is used to evaluate the number of bytes that have already been ! -! written to the allocated bitstream memory block. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! stream bitstream* - Structure that ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! unsigned int(32 bit) - Number of bites that have been written to the ! -! bitstream. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 13.05.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ -uint64 -bytes_used(bitstream const *const stream) -{ - if(stream->T == 0xFF) - { - return stream->L + 1; - } - else - { - return stream->L; - } +/*================================================================================================*/ +/** + * @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) \ + { \ + while(aux.pos + chunck_len > aux.len) \ + { \ + aux.len += aux.len / 2; \ + } \ + aux.ptr = realloc(aux.ptr, aux.len); \ + } \ + memcpy(aux.ptr + aux.pos, chunck, chunck_len); \ + aux.pos += chunck_len; \ } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: bitstream* bwc_init_stream(uchar* memory, uint32 size, char instr) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function is used to initialize a bwc bitstream. For encoding, a null pointer ! -! is passed as a memory handle and the function will allocate a memory block with the ! -! specified stream size. For decoding, a valid memory handle, passed by the function ! -! caller, will be stored in the bitstream structure. The byte buffer counter t, ! -! stream size Lmax and size increment are initialized with their appropriate values. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! size unsigned int(32 bit) - Initial size of the bwc stream. ! -! ! -! memory unsigned char - Memory handle for the bwc stream memory ! -! block. ! -! ! -! instr char - Constant used to instruct the field ! -! initialization. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! bitstream* - Memory handle for the initialized bwc stream. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 19.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ -bitstream* -init_stream(uchar* memory, uint32 size, char instr) -{ - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bitstream *stream; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(instr == 'c' || instr == 'd'); - - /*--------------------------------------------------------*\ - ! Allocate the bwc stream structure. ! - \*--------------------------------------------------------*/ - stream = calloc(1, sizeof(bitstream)); - if(!stream) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return NULL; - } - - /*--------------------------------------------------------*\ - ! Evaluate if a valid memory handle has been passed by the ! - ! function caller. ! - \*--------------------------------------------------------*/ - if(!memory) - { - /*--------------------------------------------------------*\ - ! If no valid memory handle has been passed, allocate a ! - ! memory block with the specifiec stream size. ! - \*--------------------------------------------------------*/ - stream->memory = calloc(size, sizeof(uchar)); - if(!stream->memory) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return NULL; - } - } - else - { - /*--------------------------------------------------------*\ - ! If a valid memory handle has been passed for decoding, ! - ! save the memory handle in the bwc stream structure. ! - \*--------------------------------------------------------*/ - stream->memory = memory; - } - - /*--------------------------------------------------------*\ - ! Initialize the byte buffer counter, stream size and size ! - ! increment for the current stream. ! - \*--------------------------------------------------------*/ - stream->t = (instr == 'c') ? 8 : 0; - stream->Lmax = size; - stream->size_incr = (uint64)(size / 2); - - /*--------------------------------------------------------*\ - ! Return the stream memory handle. ! - \*--------------------------------------------------------*/ - return stream; +/*================================================================================================*/ +/** + * @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) { \ + memcpy(chunck, aux.ptr + aux.pos, chunck_len); \ + aux.pos += chunck_len; \ + } else { \ + fprintf(stderr, MEMERROR); \ + } \ } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void bwc_emit_chunck(bitstream *const stream, const uchar* string, const uint64 length) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function is used to write an additional chunck of size length to a bwc bitstream. ! -! ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! stream bitstream* - Structure used to assemble a bwc bit- ! -! bitstream. ! -! ! -! chunck unsigned char* - Memory handle for a data block that is ! -! to be written to the bwc bitstream. ! -! ! -! size unsigned int(64 bit) - Size of the data block. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 22.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ -void -emit_chunck(bitstream *const stream, const uchar* chunck, const uint64 size) -{ - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 Lreq; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(stream); - assert(chunck); - - /*--------------------------------------------------------*\ - ! Evaluate the memory block size if the current chunck of ! - ! data is written to the stream. ! - \*--------------------------------------------------------*/ - Lreq = (bytes_used(stream) + size); - - /*--------------------------------------------------------*\ - ! Check if the enough memory has been allocated for the ! - ! stream to store the additional data chunck. ! - \*--------------------------------------------------------*/ - if(Lreq > stream->Lmax) - { - /*--------------------------------------------------------*\ - ! If the stream is not large enough, check if this is due ! - ! to an error encountered in a previous writing operation ! - \*--------------------------------------------------------*/ - if(!stream->error) - { - /*--------------------------------------------------------*\ - ! If the error flag is not set, increase the stream size ! - ! until it is large enough to store the additional data ! - ! chunck. ! - \*--------------------------------------------------------*/ - while(Lreq > stream->Lmax) - { - stream->Lmax += stream->size_incr + size; - stream->size_incr = (uint64)(stream->Lmax / 2); - } - - /*--------------------------------------------------------*\ - ! Reallocate the stream data block. ! - \*--------------------------------------------------------*/ - stream->memory = realloc(stream->memory, stream->Lmax); - if(!stream->memory) - { - // memory allocation error - stream->error |= 1; - stream->Lmax = 0; - return; - } - } - else - { - /*--------------------------------------------------------*\ - ! Exit to function caller if error flag has been set. ! - \*--------------------------------------------------------*/ - return; - } - } - - /*--------------------------------------------------------*\ - ! Copy the additional data to the stream memory block. ! - \*--------------------------------------------------------*/ - memcpy(stream->memory + stream->L, chunck, size); - - /*--------------------------------------------------------*\ - ! Increment the number of bytes written to the stream with ! - ! the size of the newly added data chunck. ! - \*--------------------------------------------------------*/ - stream->L += size; -} - -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void *test(void) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! DESCRIPTION NEEDED ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! stream bitstream* - Structure used to assemble a bwc bit- ! -! bitstream. ! -! ! -! size unsigned int(64 bit) - Size of the data block. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! uchar* - Data chunck requested by the function caller. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 22.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ -uchar* -get_chunck(bitstream *const stream, const uint64 size) -{ - /*-----------------------*\ - ! DEFINE CHAR VARIABLES: ! - \*-----------------------*/ - uchar *tmp; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(stream); - - /*--------------------------------------------------------*\ - ! Check if the number of bytes to be read from the stream ! - ! does not exceed the number of bytes still present in its ! - ! memory block. ! - \*--------------------------------------------------------*/ - if(bytes_used(stream) + size <= stream->Lmax) - { - /*--------------------------------------------------------*\ - ! Allocate a temporary array used to store the bytes that ! - ! are extracted from the stream. ! - \*--------------------------------------------------------*/ - tmp = calloc(size, sizeof(uchar)); - if(!tmp) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return NULL; - } - - /*--------------------------------------------------------*\ - ! Copy the bytes requested from the function caller from ! - ! the stream to the temporary data block. ! - \*--------------------------------------------------------*/ - memcpy(tmp, stream->memory + stream->L, size); - - /*--------------------------------------------------------*\ - ! Increment the number of bytes read from the bitstream. ! - \*--------------------------------------------------------*/ - stream->L += size; - - /*--------------------------------------------------------*\ - ! Return the temporary data block to the function caller. ! - \*--------------------------------------------------------*/ - return tmp; - } - else - { - /*--------------------------------------------------------*\ - ! If the requested block size exceeds the information left ! - ! in the bitstream, set the bitstream error flag and ! - ! return a NULL pointer. ! - \*--------------------------------------------------------*/ - stream->error |= 1; - return NULL; - } -} - -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void *test(void) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! DESCRIPTION NEEDED ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! - - - ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! - Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ -uchar -terminate_stream(bitstream *stream, bwc_stream *const packed_stream) -{ - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(stream); - - if(packed_stream) - { - if(stream->error) - { - return 1; - } - else if(stream->L != stream->Lmax) - { - stream->Lmax = stream->L; - stream->memory = realloc(stream->memory, stream->Lmax); - if(!stream->memory) - { - // memory allocation error - fprintf(stderr, MEMERROR); - stream->Lmax = 0; - return 1; - } - } - - packed_stream->memory = stream->memory; - packed_stream->access = stream->memory; - packed_stream->size = stream->L; - packed_stream->position = 0; - } - else - { - free(stream->memory); - } - - free(stream); - return 0; -} - -/*----------------------------------------------------------------------------------------------------------*\ -! ! -! 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) @@ -585,49 +197,129 @@ endian_conversion(void *value, } } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar read_eas3_header(bwc_data *const data) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function opens an eas3 file and checks it for its validity. Once the specified file ! -! has been verified, its header and flow field data is read and stored in the bwc_data ! -! structure. ! -! ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! filename char* - Defines the filename of the eas3 file ! -! that is to be opened and read. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! file - Defines a structure used to store all ! -! the relevant parameters and the data ! -! field of an eas3 file. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ -static uchar -read_eas3_header(bwc_data *const data) +/*================================================================================================*/ +/** + * @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) +{ + /*-----------------------*\ + ! 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.f != NULL) + free(data->field.f); + + if(data->aux.ptr != NULL) + free(data->aux.ptr); + + free(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) +{ + eas3_param_names *param_names; + assert(data); + param_names = data->param_names; + /*--------------------------------------------------------*\ + ! Check if the specified parameter name has the proper ! + ! length. ! + \*--------------------------------------------------------*/ + if((strlen(name) > 24) && name) + { + fprintf(stderr, "o==========================================================o\n"\ + "| WARNING: Invalid parameter name: %-24s|\n"\ + "| |\n"\ + "| Parameter names cannot exceed 24 characters. |\n"\ + "| |\n"\ + "o==========================================================o\n",name); + } + + /*--------------------------------------------------------*\ + ! Check if the parameter structure has already been allo- ! + ! cated. ! + \*--------------------------------------------------------*/ + if(data->param_names == NULL) + { + /*--------------------------------------------------------*\ + ! If eas3_add_param_name function is called for the first ! + ! time, allocate the parameter structure and save the root ! + ! node address. ! + \*--------------------------------------------------------*/ + data->param_names = calloc(1, sizeof(eas3_param_names)); + data->param_names->root = data->param_names; + } + else + { + /*--------------------------------------------------------*\ + ! If a new parameter is added, allocate the nex linked ! + ! list node, save the root node address in its structure ! + ! and set the linked list access pointer to the new node. ! + \*--------------------------------------------------------*/ + data->param_names->next = calloc(1, sizeof(eas3_param_names)); + data->param_names->next->root = data->param_names->root; + data->param_names->next->id = data->param_names->id + 1; + data->param_names = data->param_names->next; + } + + /*--------------------------------------------------------*\ + ! Save the name of the new parameter its precision in the ! + ! structure of the new node. ! + \*--------------------------------------------------------*/ + 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; - uint8 precision; /*-----------------------*\ ! DEFINE CHAR VARIABLES: ! @@ -638,14 +330,119 @@ read_eas3_header(bwc_data *const data) /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - bwc_gl_inf *info; - bitstream *aux; - eas3_std_params params; + 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*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*sizeof(double)); + } + + return 0; +} + +/*================================================================================================*/ +/** + * @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) +{ + /*-----------------------*\ + ! DEFINE INT VARIABLES: ! + \*-----------------------*/ + uint64 Lread; + uint64 i; /*-----------------------*\ - ! DEFINE FILE POINTER: ! + ! DEFINE CHAR VARIABLES: ! \*-----------------------*/ - FILE *fp; + uchar *buffer_char; + char param_name[ATTRLEN + 1] = {}; + + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + eas3_std_params *params; /*-----------------------*\ ! DEFINE ASSERTIONS: ! @@ -653,11 +450,10 @@ read_eas3_header(bwc_data *const data) assert(data); /*--------------------------------------------------------*\ - ! Save the file pointer and data info structure in tempo- ! - ! rary variables to make the code more readable. ! + ! Save the eas3_std_params structure in temporary ! + ! variables to make the code more readable. ! \*--------------------------------------------------------*/ - fp = data->fp; - info = &data->info; + params = &data->params; /*--------------------------------------------------------*\ ! Allocate the character buffer used to store chunks of ! @@ -698,26 +494,16 @@ read_eas3_header(bwc_data *const data) return 1; } - /*--------------------------------------------------------*\ - ! Allocate the auxiliary information packed stream. ! - \*--------------------------------------------------------*/ - data->codestream.aux = calloc(1, sizeof(bwc_stream)); - if(!data->codestream.aux) - { - // memory allocation error - fprintf(stderr, MEMERROR); - free(buffer_char); - return 1; - } - /*--------------------------------------------------------*\ ! Initialize the stream for the auxiliary information mem- ! ! ory block. The initial size of the auxiliary memory ! ! block has been chosen arbitrarily and should be large ! ! enough to prevent excessive reallocation. ! \*--------------------------------------------------------*/ - aux = init_stream(NULL, AUX_SIZE, 'c'); - if(!aux) + data->aux.ptr = calloc(AUX_SIZE, sizeof(uchar)); + data->aux.pos = 0; + data->aux.len = AUX_SIZE; + if(!data->aux.ptr) { // memory allocation error fprintf(stderr, MEMERROR); @@ -730,7 +516,7 @@ read_eas3_header(bwc_data *const data) ! present the eas3 standard parameters. The information ! ! is stored in the eas3_std_params structure. ! \*--------------------------------------------------------*/ - if(fread(¶ms, sizeof(uint64), 22, fp) != 22) + if(fread(params, sizeof(uint64), 22, fp) != 22) { // invalid read fprintf(stderr, RDERROR); @@ -741,7 +527,7 @@ read_eas3_header(bwc_data *const data) /*--------------------------------------------------------*\ ! Check if the specified file is of the EAS3 type. ! \*--------------------------------------------------------*/ - if(params.file_type == EAS2_TYPE) + if(params->file_type == EAS2_TYPE) { // invalid file format fprintf(stderr, "o##########################################################o\n"\ @@ -751,50 +537,29 @@ read_eas3_header(bwc_data *const data) return 1; } - /*--------------------------------------------------------*\ - ! Emit a file format hash to the aux stream to identify it ! - ! as a eas3 auxiliary information block. This hash can be ! - ! used to properly handle decompression into an eas3 file ! - ! or conversion to other file formats. ! - \*--------------------------------------------------------*/ - // emit_symbol(aux, hash("eas3"), 8); - /*--------------------------------------------------------*\ ! Emit the standard parameters to the auxiliary informa- ! ! tion information memory block. ! \*--------------------------------------------------------*/ - emit_chunck(aux, (uchar*)¶ms, 176); + aux_enqueue(data->aux, (uchar*)params, 176); /*--------------------------------------------------------*\ ! Convert the parameters required for the bwc compression ! ! stage to little endian and store them in the file info ! ! structure. ! \*--------------------------------------------------------*/ - endian_conversion(¶ms.nzs, 8); - info->nTS = (uint16)params.nzs; + endian_conversion(¶ms->nts, 8); - endian_conversion(¶ms.npar, 8); - info->nPar = (uint8)params.npar; + endian_conversion(¶ms->npar, 8); - endian_conversion(¶ms.ndim1, 8); - info->nX = (uint64)params.ndim1; + endian_conversion(¶ms->ndim1, 8); - endian_conversion(¶ms.ndim2, 8); - info->nY = (uint64)params.ndim2; + endian_conversion(¶ms->ndim2, 8); - endian_conversion(¶ms.ndim3, 8); - info->nZ = (uint64)params.ndim3; + endian_conversion(¶ms->ndim3, 8); - endian_conversion(¶ms.accuracy, 8); - if(params.accuracy == 1) - { - precision = 4; - } - else if(params.accuracy == 2) - { - precision = 8; - } - else + 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"\ @@ -807,20 +572,20 @@ read_eas3_header(bwc_data *const data) ! Convert the size parameters, used to load the rest of the! ! header, to little endian. ! \*--------------------------------------------------------*/ - endian_conversion(¶ms.size_time, 8); - endian_conversion(¶ms.size_parameter, 8); - endian_conversion(¶ms.size_dim1, 8); - endian_conversion(¶ms.size_dim2, 8); - endian_conversion(¶ms.size_dim3, 8); - endian_conversion(¶ms.udef_char_size, 8); - endian_conversion(¶ms.udef_int_size, 8); - endian_conversion(¶ms.udef_real_size, 8); + endian_conversion(¶ms->size_time, 8); + endian_conversion(¶ms->size_parameter, 8); + endian_conversion(¶ms->size_dim1, 8); + endian_conversion(¶ms->size_dim2, 8); + endian_conversion(¶ms->size_dim3, 8); + endian_conversion(¶ms->udef_char_size, 8); + endian_conversion(¶ms->udef_int_size, 8); + endian_conversion(¶ms->udef_real_size, 8); /*--------------------------------------------------------*\ ! Allocate the time step array. If successful, read the ! ! timesteps from the file stream. ! \*--------------------------------------------------------*/ - buffer_char = realloc(buffer_char, info->nTS * sizeof(uint64)); + buffer_char = realloc(buffer_char, params->nts * sizeof(uint64)); if(!buffer_char) { // memory allocation error @@ -828,7 +593,7 @@ read_eas3_header(bwc_data *const data) return 1; } - if(fread(buffer_char, sizeof(uint64), info->nTS, fp) != info->nTS) + if(fread(buffer_char, sizeof(uint64), params->nts, fp) != params->nts) { // invalid read fprintf(stderr, RDERROR); @@ -840,19 +605,19 @@ read_eas3_header(bwc_data *const data) ! Emit the time step array to the auxiliary information ! ! memory block. ! \*--------------------------------------------------------*/ - emit_chunck(aux, buffer_char, info->nTS * sizeof(uint64)); + aux_enqueue(data->aux, buffer_char, params->nts * sizeof(uint64)); /*--------------------------------------------------------*\ ! Check if any attributes have been specified in the eas3 ! ! file. ! \*--------------------------------------------------------*/ - if(params.attribute_mode == EAS3_ALL_ATTR) + if(params->attribute_mode == EAS3_ALL_ATTR) { /*--------------------------------------------------------*\ ! Allocate the buffer character array. If successful, read ! ! the timestep attributes from the file stream. ! \*--------------------------------------------------------*/ - buffer_char = realloc(buffer_char, info->nTS * ATTRLEN * sizeof(char)); + buffer_char = realloc(buffer_char, params->nts * ATTRLEN * sizeof(char)); if(!buffer_char) { // memory allocation error @@ -861,7 +626,7 @@ read_eas3_header(bwc_data *const data) return 1; } - if(fread(buffer_char, sizeof(char), info->nTS * ATTRLEN, fp) != (info->nTS * ATTRLEN)) + if(fread(buffer_char, sizeof(char), params->nts * ATTRLEN, fp) != (params->nts * ATTRLEN)) { // invalid read fprintf(stderr, RDERROR); @@ -873,9 +638,9 @@ read_eas3_header(bwc_data *const data) ! Emit the timestep attribute array to the auxiliary infor-! ! mation memory block. ! \*--------------------------------------------------------*/ - emit_chunck(aux, buffer_char, info->nTS * ATTRLEN * sizeof(char)); + aux_enqueue(data->aux, buffer_char, params->nts * ATTRLEN * sizeof(char)); - for(i = 0; i < info->nPar; ++i) + for(i = 0; i < params->npar; ++i) { /*--------------------------------------------------------*\ ! Read the parameter name from the file stream and add all ! @@ -890,13 +655,9 @@ read_eas3_header(bwc_data *const data) return 1; } - bwc_add_param(data, param_name, precision); + 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); } } @@ -906,15 +667,15 @@ read_eas3_header(bwc_data *const data) ! the eas3 file header. ! \*--------------------------------------------------------*/ Lread = 0; - Lread += (params.attribute_mode == EAS3_ALL_ATTR) ? 3 * ATTRLEN : 0; - Lread += (params.gmode_time > EAS3_NO_G) ? params.size_time * sizeof(uint64) : 0; - Lread += (params.gmode_param > EAS3_NO_G) ? params.size_parameter * sizeof(uint64) : 0; - Lread += (params.gmode_dim1 > EAS3_NO_G) ? params.size_dim1 * sizeof(uint64) : 0; - Lread += (params.gmode_dim2 > EAS3_NO_G) ? params.size_dim2 * sizeof(uint64) : 0; - Lread += (params.gmode_dim3 > EAS3_NO_G) ? params.size_dim3 * sizeof(uint64) : 0; - Lread += (params.udef_param == EAS3_ALL_UDEF) ? params.udef_char_size * sizeof(char) * UDEFLEN + - params.udef_int_size * sizeof(uint64) + - params.udef_real_size * sizeof(double) : 0; + Lread += (params->attribute_mode == EAS3_ALL_ATTR) ? 3 * ATTRLEN : 0; + Lread += (params->gmode_time > EAS3_NO_G) ? params->size_time * sizeof(uint64) : 0; + Lread += (params->gmode_param > EAS3_NO_G) ? params->size_parameter * sizeof(uint64) : 0; + Lread += (params->gmode_dim1 > EAS3_NO_G) ? params->size_dim1 * sizeof(uint64) : 0; + Lread += (params->gmode_dim2 > EAS3_NO_G) ? params->size_dim2 * sizeof(uint64) : 0; + Lread += (params->gmode_dim3 > EAS3_NO_G) ? params->size_dim3 * sizeof(uint64) : 0; + Lread += (params->udef_param == EAS3_ALL_UDEF) ? params->udef_char_size * sizeof(char) * UDEFLEN + + params->udef_int_size * sizeof(uint64) + + params->udef_real_size * sizeof(double) : 0; /*--------------------------------------------------------*\ ! Reallocate the buffer character array to allow for the ! @@ -944,7 +705,7 @@ read_eas3_header(bwc_data *const data) ! Emit the remaining header information the the auxiliary ! ! information stream. ! \*--------------------------------------------------------*/ - emit_chunck(aux, buffer_char, Lread); + aux_enqueue(data->aux, buffer_char, Lread); /*--------------------------------------------------------*\ ! Free the buffer character array. ! @@ -956,52 +717,35 @@ read_eas3_header(bwc_data *const data) ! ful, the address to the aux memory block stored is ! ! stored in the file structure alongside its size. ! \*--------------------------------------------------------*/ - if(terminate_stream(aux, data->codestream.aux)) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return 1; - } + if(data->aux.pos != data->aux.len) + { + data->aux.len = data->aux.pos; + data->aux.ptr = realloc(data->aux.ptr, data->aux.len); + if(!data->aux.ptr) + { + // memory allocation error + fprintf(stderr, MEMERROR); + data->aux.len = 0; + return 1; + } + } return 0; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar read_eas3_header(bwc_data *const data) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function opens an eas3 file and checks it for its validity. Once the specified file ! -! has been verified, its header and flow field data is read and stored in the bwc_data ! -! structure. ! -! ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! filename char* - Defines the filename of the eas3 file ! -! that is to be opened and read. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! file - Defines a structure used to store all ! -! the relevant parameters and the data ! -! field of an eas3 file. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @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(bwc_data *const data) +write_eas3_header(FILE *const fp, eas3_data *const data) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -1016,28 +760,14 @@ write_eas3_header(bwc_data *const data) /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - bwc_gl_inf *info; - bitstream *aux; eas3_std_params *params; - bwc_cmd_opts_ll *param; + eas3_param_names *param_names; - /*-----------------------*\ - ! DEFINE FILE POINTER: ! - \*-----------------------*/ - FILE *fp; - /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ assert(data); - /*--------------------------------------------------------*\ - ! Save the file pointer and data info structure in tempo- ! - ! rary variables to make the code more readable. ! - \*--------------------------------------------------------*/ - fp = data->fp; - info = &data->info; - /*--------------------------------------------------------*\ ! Write the valid EAS3 identifier to the specified file. ! \*--------------------------------------------------------*/ @@ -1048,17 +778,22 @@ write_eas3_header(bwc_data *const data) return 1; } - /*--------------------------------------------------------*\ - ! Initialize the auxiliary information stream. ! - \*--------------------------------------------------------*/ - aux = init_stream(data->codestream.aux->memory, - data->codestream.aux->size, 'd'); + // Rewind aux + data->aux.pos = 0; /*--------------------------------------------------------*\ ! Get the standard parameters from the auxiliary informa- ! ! memory block and write them to the file stream. ! \*--------------------------------------------------------*/ - params = (eas3_std_params*)get_chunck(aux, 176); + params = calloc(1, sizeof(eas3_std_params)); + if(!params) + { + // memory allocation error + fprintf(stderr, MEMERROR); + free(params); + return 1; + } + aux_dequeue(data->aux, params, sizeof(eas3_std_params)); if(fwrite(params, sizeof(uint64), 22, fp) != 22) { @@ -1071,7 +806,13 @@ write_eas3_header(bwc_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); @@ -1081,12 +822,14 @@ write_eas3_header(bwc_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 ! ! and write it to the file stream. ! \*--------------------------------------------------------*/ - buffer_char = get_chunck(aux, info->nTS * sizeof(uint64)); + buffer_char = calloc(data->params.nts * sizeof(uint64), sizeof(uchar)); if(!buffer_char) { // memory allocation error @@ -1094,8 +837,9 @@ write_eas3_header(bwc_data *const data) free(buffer_char); return 1; } + aux_dequeue(data->aux, buffer_char, data->params.nts * sizeof(uint64)); - if(fwrite(buffer_char, sizeof(uint64), info->nTS, fp) != info->nTS) + if(fwrite(buffer_char, sizeof(uint64), data->params.nts, fp) != data->params.nts) { // invalid read fprintf(stderr, WRTERROR); @@ -1115,7 +859,7 @@ write_eas3_header(bwc_data *const data) ! the timestep attribute array from the auxiliary informa- ! ! tion block and write it to the file stream. ! \*--------------------------------------------------------*/ - buffer_char = get_chunck(aux, info->nTS * ATTRLEN); + buffer_char = calloc(data->params.nts * ATTRLEN, sizeof(uchar)); if(!buffer_char) { // memory allocation error @@ -1123,8 +867,9 @@ write_eas3_header(bwc_data *const data) free(buffer_char); return 1; } + aux_dequeue(data->aux, buffer_char, data->params.nts * ATTRLEN); - if(fwrite(buffer_char, sizeof(uchar), info->nTS * ATTRLEN, fp) != (info->nTS * ATTRLEN)) + if(fwrite(buffer_char, sizeof(uchar), data->params.nts * ATTRLEN, fp) != (data->params.nts * ATTRLEN)) { // invalid read fprintf(stderr, WRTERROR); @@ -1136,17 +881,17 @@ write_eas3_header(bwc_data *const data) /*--------------------------------------------------------*\ ! Loop through the parameter array and... ! \*--------------------------------------------------------*/ - if(data->info.parameter) + if(data->param_names) { - param = data->info.parameter->root; + param_names = data->param_names->root; - while(param != NULL) + while(param_names != NULL) { /*--------------------------------------------------------*\ ! ... write the parameter name from the info structure to ! ! the file stream. ! \*--------------------------------------------------------*/ - if(fwrite(param->name, sizeof(char), ATTRLEN, fp) != ATTRLEN) + if(fwrite(param_names->name, sizeof(char), ATTRLEN, fp) != ATTRLEN) { // invalid read fprintf(stderr, WRTERROR); @@ -1154,7 +899,7 @@ write_eas3_header(bwc_data *const data) return 1; } - param = param -> next; + param_names = param_names->next; } } } @@ -1179,7 +924,7 @@ write_eas3_header(bwc_data *const data) ! the remaining eas header bytes from the auxiliary infor- ! ! mation block and write it to the file stream. ! \*--------------------------------------------------------*/ - buffer_char = get_chunck(aux, Lwrite); + buffer_char = calloc(Lwrite, sizeof(uchar)); if(!buffer_char) { // memory allocation error @@ -1187,6 +932,7 @@ write_eas3_header(bwc_data *const data) free(buffer_char); return 1; } + aux_dequeue(data->aux, buffer_char, Lwrite); if(fwrite(buffer_char, sizeof(uchar), Lwrite, fp) != Lwrite) { @@ -1198,10 +944,8 @@ write_eas3_header(bwc_data *const data) free(buffer_char); /*--------------------------------------------------------*\ - ! Free the auxiliary information memory block stream and ! - ! params structure. ! + ! Free the params structure. ! \*--------------------------------------------------------*/ - free(aux); free(params); return 0; @@ -1213,41 +957,17 @@ write_eas3_header(bwc_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 ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ -bwc_data* +/*================================================================================================*/ +/** + * @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) { /*-----------------------*\ @@ -1256,16 +976,17 @@ read_eas3(char *const filename) uint64 Lfield; uint64 i; uint32 root; + FILE *fp; /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - bwc_data *data; + eas3_data *data; /*--------------------------------------------------------*\ ! Allocate the data structure. ! \*--------------------------------------------------------*/ - data = calloc(1, sizeof(bwc_data)); + data = calloc(1, sizeof(eas3_data)); if(!data) { // memory allocation error @@ -1273,23 +994,16 @@ read_eas3(char *const filename) return NULL; } - /*--------------------------------------------------------*\ - ! Set the file identifier used to select the appropriate ! - ! write operation during decompression. ! - \*--------------------------------------------------------*/ - strncpy(data->info.f_ext, "eas", 4); - /*--------------------------------------------------------*\ ! Open the specified file for reading. If the file doesn't ! ! exist, exit the bwc command-line tool. ! \*--------------------------------------------------------*/ - if((data->fp = fopen(filename, "rb")) == NULL) + if((fp = fopen(filename, "rb")) == NULL) { // error opening file fprintf(stderr, "o##########################################################o\n"\ "| ERROR: Could not open or read %-25s|\n"\ "o##########################################################o\n", filename); - bwc_free_data(data); return NULL; } @@ -1297,10 +1011,10 @@ read_eas3(char *const filename) ! Parse the eas3 header and store the information in the ! ! data structure. ! \*--------------------------------------------------------*/ - if(read_eas3_header(data)) + if(read_eas3_header(fp, data)) { //error reading eas3 header - bwc_free_data(data); + eas3_free_data(data); } /*--------------------------------------------------------*\ @@ -1308,19 +1022,19 @@ read_eas3(char *const filename) ! file and store the information in the bwc_gl_data struc- ! ! ture. ! \*--------------------------------------------------------*/ - root = ftell(data->fp); - fseek(data->fp, 0L, SEEK_END); - Lfield = (ftell(data->fp) - root) / sizeof(double); - fseek(data->fp, root, SEEK_SET); + root = ftell(fp); + fseek(fp, 0L, SEEK_END); + Lfield = (ftell(fp) - root) / sizeof(double); + fseek(fp, root, SEEK_SET); /*--------------------------------------------------------*\ ! Check if the file_size coincide with the specified dimen-! ! sions, timesteps number of parameters or bitdepth speci- ! ! fied in the eas3 file header. ! \*--------------------------------------------------------*/ - if(Lfield != data->info.nX * data->info.nY * - data->info.nZ * data->info.nTS * - data->info.nPar) + if(Lfield != data->params.ndim1 * data->params.ndim2 * + data->params.ndim3 * data->params.nts * + data->params.npar) { // error in file size fprintf(stderr, "o##########################################################o\n"\ @@ -1329,11 +1043,11 @@ read_eas3(char *const filename) "| and number of parameters specified in the file |\n"\ "| header. |\n"\ "o##########################################################o\n"); - bwc_free_data(data); + eas3_free_data(data); return NULL; } - if(data->info.parameter->precision == 4) + if(data->params.accuracy == 1) { /*--------------------------------------------------------*\ ! Allocate the real field that will hold the numerical ! @@ -1341,22 +1055,22 @@ read_eas3(char *const filename) \*--------------------------------------------------------*/ data->field.d = NULL; data->field.f = calloc(Lfield, sizeof(float)); - if(!data->field.d) + if(!data->field.f) { // memory allocation error fprintf(stderr, MEMERROR); - bwc_free_data(data); + eas3_free_data(data); return NULL; } /*--------------------------------------------------------*\ ! Read the flow field data from the specified eas3 file. ! \*--------------------------------------------------------*/ - if(fread(data->field.f, sizeof(float), Lfield, data->fp) != Lfield) + if(fread(data->field.f, sizeof(float), Lfield, fp) != Lfield) { // invalid read fprintf(stderr, RDERROR); - bwc_free_data(data); + eas3_free_data(data); return NULL; } @@ -1369,7 +1083,7 @@ read_eas3(char *const filename) endian_conversion(&data->field.f[i], 4); } } - else if(data->info.parameter->precision == 8) + else if(data->params.accuracy == 2) { /*--------------------------------------------------------*\ ! Allocate the real field that will hold the numerical ! @@ -1381,18 +1095,18 @@ read_eas3(char *const filename) { // memory allocation error fprintf(stderr, MEMERROR); - bwc_free_data(data); + eas3_free_data(data); return NULL; } /*--------------------------------------------------------*\ ! Read the flow field data from the specified eas3 file. ! \*--------------------------------------------------------*/ - if(fread(data->field.d, sizeof(double), Lfield, data->fp) != Lfield) + if(fread(data->field.d, sizeof(double), Lfield, fp) != Lfield) { // invalid read fprintf(stderr, RDERROR); - bwc_free_data(data); + eas3_free_data(data); return NULL; } @@ -1410,53 +1124,30 @@ read_eas3(char *const filename) ! Close the file pointer and return the bwc_data structure ! ! to the function caller. ! \*--------------------------------------------------------*/ - fclose(data->fp); - data->fp = NULL; + fclose(fp); + fp = NULL; return data; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar write_eas3(bwc_data *const file, char *const filename) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function creates a valid eas3 file from the information stored in the bwc_data ! -! structure. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! filename char* - Defines the filename of the eas3 file ! -! that is to be opened and read. ! -! ! -! file bwc_data* - Defines a structure used to store all ! -! the relevant parameters and the data ! -! field of an eas3 file. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! uchar - Returns an unsigned char for error handling. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @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(bwc_data *const data, char *const filename) +write_eas3(eas3_data *const data, char *const filename) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ uint64 Lfield; uint64 i; + FILE *fp; /*-----------------------*\ ! DEFINE ASSERTIONS: ! @@ -1468,7 +1159,7 @@ write_eas3(bwc_data *const data, char *const filename) ! exist, discard its content. If the file cannot be creat- ! ! ed, exit the bwc command-line tool. ! \*--------------------------------------------------------*/ - if((data->fp = fopen(filename, "wb")) == NULL) + if((fp = fopen(filename, "wb")) == NULL) { // error opening file fprintf(stderr, "o##########################################################o\n"\ @@ -1480,7 +1171,7 @@ write_eas3(bwc_data *const data, char *const filename) /*--------------------------------------------------------*\ ! Write the eas3 header to the specified file. ! \*--------------------------------------------------------*/ - if(write_eas3_header(data)) + if(write_eas3_header(fp, data)) { //error reading eas3 header return 1; @@ -1490,10 +1181,10 @@ write_eas3(bwc_data *const data, char *const filename) ! Calculate the size of the data field used for the endian ! ! conversion and write operations. ! \*--------------------------------------------------------*/ - Lfield = data->info.nX * data->info.nY * - data->info.nZ * data->info.nTS * data->info.nPar; + Lfield = data->params.ndim1 * data->params.ndim2 * + data->params.ndim3 * data->params.nts * data->params.npar; - if(data->info.parameter->precision == 4) + if(data->params.accuracy == 1) { /*--------------------------------------------------------*\ ! Convert the flow field data from big endian to endian. ! @@ -1506,14 +1197,14 @@ write_eas3(bwc_data *const data, char *const filename) /*--------------------------------------------------------*\ ! Write the flow field data to the specified eas3 file. ! \*--------------------------------------------------------*/ - if(fwrite(data->field.f, sizeof(float), Lfield, data->fp) != Lfield) + if(fwrite(data->field.f, sizeof(float), Lfield, fp) != Lfield) { // invalid read fprintf(stderr, WRTERROR); return 1; } } - else if(data->info.parameter->precision == 8) + else if(data->params.accuracy == 2) { /*--------------------------------------------------------*\ ! Convert the flow field data from big endian to endian. ! @@ -1526,7 +1217,7 @@ write_eas3(bwc_data *const data, char *const filename) /*--------------------------------------------------------*\ ! Write the flow field data to the specified eas3 file. ! \*--------------------------------------------------------*/ - if(fwrite(data->field.d, sizeof(double), Lfield, data->fp) != Lfield) + if(fwrite(data->field.d, sizeof(double), Lfield, fp) != Lfield) { // invalid read fprintf(stderr, WRTERROR); @@ -1537,7 +1228,7 @@ write_eas3(bwc_data *const data, char *const filename) /*--------------------------------------------------------*\ ! Close the file pointer and return to the function caller.! \*--------------------------------------------------------*/ - fclose(data->fp); - data->fp = NULL; + fclose(fp); + fp = NULL; return 0; } \ No newline at end of file diff --git a/src/library/bitstream.c b/src/library/bitstream.c index 1618c87..2780b65 100755 --- a/src/library/bitstream.c +++ b/src/library/bitstream.c @@ -107,8 +107,6 @@ bytes_used(bitstream const *const stream) } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: bitstream* bwc_init_stream(uchar* memory, uint32 size, char instr) ! -! -------------- ! ! ! ! DESCRIPTION: ! ! ------------ ! @@ -145,7 +143,7 @@ bytes_used(bitstream const *const stream) ! ! \*----------------------------------------------------------------------------------------------------------*/ bitstream* -init_stream(uchar* memory, uint32 size, char instr) +init_bitstream(uchar* memory, uint32 size, char instr) { /*-----------------------*\ ! DEFINE STRUCTS: ! @@ -155,6 +153,7 @@ init_stream(uchar* memory, uint32 size, char instr) /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ + assert(memory); assert(instr == 'c' || instr == 'd'); /*--------------------------------------------------------*\ @@ -168,37 +167,11 @@ init_stream(uchar* memory, uint32 size, char instr) return NULL; } - /*--------------------------------------------------------*\ - ! Evaluate if a valid memory handle has been passed by the ! - ! function caller. ! - \*--------------------------------------------------------*/ - if(!memory) - { - /*--------------------------------------------------------*\ - ! If no valid memory handle has been passed, allocate a ! - ! memory block with the specifiec stream size. ! - \*--------------------------------------------------------*/ - stream->memory = calloc(size, sizeof(uchar)); - if(!stream->memory) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return NULL; - } - } - else - { - /*--------------------------------------------------------*\ - ! If a valid memory handle has been passed for decoding, ! - ! save the memory handle in the bwc stream structure. ! - \*--------------------------------------------------------*/ - stream->memory = memory; - } - /*--------------------------------------------------------*\ ! Initialize the byte buffer counter, stream size and size ! ! increment for the current stream. ! \*--------------------------------------------------------*/ + stream->memory = memory; stream->t = (instr == 'c') ? 8 : 0; stream->Lmax = size; stream->size_incr = (uint64)(size / 2); @@ -247,11 +220,6 @@ init_stream(uchar* memory, uint32 size, char instr) void emit_chunck(bitstream *const stream, const uchar* chunck, const uint64 size) { - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64 Lreq; - /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ @@ -259,54 +227,30 @@ emit_chunck(bitstream *const stream, const uchar* chunck, const uint64 size) assert(chunck); /*--------------------------------------------------------*\ - ! Evaluate the memory block size if the current chunck of ! - ! data is written to the stream. ! + ! Check if an error was encountered in a previous writing ! + ! operation ! \*--------------------------------------------------------*/ - Lreq = (bytes_used(stream) + size); - - /*--------------------------------------------------------*\ - ! Check if the enough memory has been allocated for the ! - ! stream to store the additional data chunck. ! - \*--------------------------------------------------------*/ - if(Lreq > stream->Lmax) + if(!stream->error) { /*--------------------------------------------------------*\ - ! If the stream is not large enough, check if this is due ! - ! to an error encountered in a previous writing operation ! + ! Check if the enough memory has been allocated for the ! + ! stream to store the additional symbol. ! \*--------------------------------------------------------*/ - if(!stream->error) + if((bytes_used(stream) + size) > stream->Lmax) { - /*--------------------------------------------------------*\ - ! If the error flag is not set, increase the stream size ! - ! until it is large enough to store the additional data ! - ! chunck. ! - \*--------------------------------------------------------*/ - while(Lreq > stream->Lmax) - { - stream->Lmax += stream->size_incr + size; - stream->size_incr = (uint64)(stream->Lmax / 2); - } - - /*--------------------------------------------------------*\ - ! Reallocate the stream data block. ! - \*--------------------------------------------------------*/ - stream->memory = realloc(stream->memory, stream->Lmax); - if(!stream->memory) - { - // memory allocation error - stream->error |= 1; - stream->Lmax = 0; - return; - } - } - else - { - /*--------------------------------------------------------*\ - ! Exit to function caller if error flag has been set. ! - \*--------------------------------------------------------*/ + // memory allocation error + stream->error |= 1; + stream->Lmax = 0; return; } } + else + { + /*--------------------------------------------------------*\ + ! Exit to function caller if error flag has been set. ! + \*--------------------------------------------------------*/ + return; + } /*--------------------------------------------------------*\ ! Copy the additional data to the stream memory block. ! @@ -370,44 +314,30 @@ emit_symbol(bitstream *const stream, const uint64 symbol, const uint8 size) assert(stream); /*--------------------------------------------------------*\ - ! Check if the enough memory has been allocated for the ! - ! stream to store the additional symbol. ! + ! Check if an error was encountered in a previous writing ! + ! operation ! \*--------------------------------------------------------*/ - if((bytes_used(stream) + size) > stream->Lmax) + if(!stream->error) { /*--------------------------------------------------------*\ - ! If the stream is not large enough, check if this is due ! - ! to an error encountered in a previous writing operation ! + ! Check if the enough memory has been allocated for the ! + ! stream to store the additional symbol. ! \*--------------------------------------------------------*/ - if(!stream->error) + if((bytes_used(stream) + size) > stream->Lmax) { - /*--------------------------------------------------------*\ - ! If the error flag is not set, increment the stream size ! - ! to store the additional symbol. ! - \*--------------------------------------------------------*/ - stream->Lmax += stream->size_incr; - stream->size_incr = (uint64)(stream->Lmax / 2); - - /*--------------------------------------------------------*\ - ! Reallocate the stream data block. ! - \*--------------------------------------------------------*/ - stream->memory = realloc(stream->memory, stream->Lmax); - if(!stream->memory) - { - // memory allocation error - stream->error |= 1; - stream->Lmax = 0; - return; - } - } - else - { - /*--------------------------------------------------------*\ - ! Exit to function caller if error flag has been set. ! - \*--------------------------------------------------------*/ + // memory allocation error + stream->error |= 1; + stream->Lmax = 0; return; } } + else + { + /*--------------------------------------------------------*\ + ! Exit to function caller if error flag has been set. ! + \*--------------------------------------------------------*/ + return; + } /*--------------------------------------------------------*\ ! Copy the additional symbol to the stream memory block ! @@ -868,76 +798,79 @@ flush_stream(bitstream *const stream) } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void *test(void) ! -! -------------- ! -! ! ! DESCRIPTION: ! ! ------------ ! -! DESCRIPTION NEEDED ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! - - - ! +! Shrinks the bitstream memory to the actually filled range. ! ! ! ! RETURN VALUE: ! ! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! - Patrick Vogler B87D120 V 0.1.0 function created ! +! Returns 0 if successfull and 1 if memory could not be resized. ! ! ! \*----------------------------------------------------------------------------------------------------------*/ uchar -terminate_stream(bitstream *stream, bwc_stream *const packed_stream) +shrink_to_fit(bitstream *const stream) { /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ assert(stream); - if(packed_stream) + if(stream->error) { - if(stream->error) + return 1; + } + else if(stream->L > stream->Lmax) + { + stream->Lmax = stream->L; + stream->memory = realloc(stream->memory, stream->Lmax); + if(!stream->memory) { + // memory allocation error + fprintf(stderr, MEMERROR); + stream->Lmax = 0; return 1; } - else if(stream->L != stream->Lmax) - { - stream->Lmax = stream->L; - stream->memory = realloc(stream->memory, stream->Lmax); - if(!stream->memory) - { - // memory allocation error - fprintf(stderr, MEMERROR); - stream->Lmax = 0; - return 1; - } - } - - packed_stream->memory = stream->memory; - packed_stream->access = stream->memory; - packed_stream->size = stream->L; - packed_stream->position = 0; } - else - { - free(stream->memory); - } - - free(stream); return 0; } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void release_packed_stream(bwc_stream *stream) ! +! DESCRIPTION: ! +! ------------ ! +! Swap memory pointer and size to span. Invalidates stream pointers. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Returns 0 if successfull and 1 if stream had previous memory error. ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +uchar +transfer_to_span(bitstream *const stream, bwc_span *const span) +{ + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(stream); + assert(span); + + if(stream->error) + { + return 1; + } + + span->memory = stream->memory; + span->access = stream->memory; + span->size = stream->L; + span->position = 0; + + stream->memory = NULL; + stream->L = 0; + + return 0; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! FUNCTION NAME: void release_packed_stream(bwc_span *stream) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -949,7 +882,7 @@ terminate_stream(bitstream *stream, bwc_stream *const packed_stream) ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! stream bwc_stream - Packed bitstream used to store parts of ! +! stream bwc_span - Packed bitstream used to store parts of ! ! the bwc codestream. ! ! ! ! RETURN VALUE: ! @@ -967,7 +900,7 @@ terminate_stream(bitstream *stream, bwc_stream *const packed_stream) ! ! \*----------------------------------------------------------------------------------------------------------*/ void -release_packed_stream(bwc_stream *stream) +release_packed_stream(bwc_span *stream) { /*-----------------------*\ ! DEFINE ASSERTIONS: ! diff --git a/src/library/codestream.c b/src/library/codestream.c index 24af2f4..aec991c 100755 --- a/src/library/codestream.c +++ b/src/library/codestream.c @@ -104,7 +104,7 @@ can_read(bitstream *const stream, const uint64 length) } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void codestream_write_header(bitstream *const stream, bwc_field *const field) ! +! FUNCTION NAME: void codestream_write_header(bitstream *const stream, bwc_codec *const codec) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -116,7 +116,7 @@ can_read(bitstream *const stream, const uint64 length) ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! +! codec bwc_codec* - Structure defining the compression/ ! ! decompression stage. ! ! ! ! stream bitstream* - Structure used to assemble a bwc bit- ! @@ -138,7 +138,8 @@ can_read(bitstream *const stream, const uint64 length) \*----------------------------------------------------------------------------------------------------------*/ static void codestream_write_header(bitstream *const stream, - bwc_field *const field) + bwc_codec *const codec, + bwc_stream *const data) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -155,33 +156,27 @@ codestream_write_header(bitstream *const stream, \*-----------------------*/ bwc_gl_ctrl *control; bwc_gl_inf *info; - bwc_tile *tile; - bwc_parameter *parameter; - bwc_stream *aux; - bwc_stream *com; + bwc_span *aux; + bwc_span *com; /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ assert(stream); - assert(field); + assert(codec); /*--------------------------------------------------------*\ ! Save the global as well as the subband control and info ! ! structure to temporary variables to make the code more ! ! readable. ! \*--------------------------------------------------------*/ - info = field->info; - control = &field->control; + info = &codec->info; + control = &codec->control; - tile = &field->tile[0]; - - parameter = &tile->parameter[0]; - - aux = field->aux; - com = field->com; + aux = data->codestream.aux; + com = data->codestream.com; - Linf = 40 + info->nPar * 25; + Linf = 31; Lctr = 50 + control->nLayers * 4; Leoh = info->nPar * control->nTiles * 2 * PREC_BYTE; Lcss = control->codestreamSize; @@ -193,16 +188,10 @@ codestream_write_header(bitstream *const stream, emit_symbol(stream, info->nX, 8); emit_symbol(stream, info->nY, 8); emit_symbol(stream, info->nZ, 8); - emit_symbol(stream, info->nTS, 2); + emit_symbol(stream, info->nTS, 8); emit_symbol(stream, info->nPar, 1); - emit_symbol(stream, info->precision, 1); - emit_chunck(stream, (uchar*)info->f_ext, 10); - - for(p = 0; p < info->nPar; ++p) - { - emit_chunck(stream, (uchar*)parameter[p].info.name, 24); - emit_symbol(stream, parameter[p].info.precision, 1); - } + emit_symbol(stream, (uint8)info->data_prec, 1); + emit_symbol(stream, (uint8)info->codec_prec, 1); emit_symbol(stream, SGC, 2); emit_symbol(stream, Lctr, 2); @@ -239,7 +228,7 @@ codestream_write_header(bitstream *const stream, emit_symbol(stream, control->tileSizeX, 8); emit_symbol(stream, control->tileSizeY, 8); emit_symbol(stream, control->tileSizeZ, 8); - emit_symbol(stream, control->tileSizeTS, 2); + emit_symbol(stream, control->tileSizeTS, 8); emit_symbol(stream, control->nLayers, 1); @@ -274,21 +263,21 @@ codestream_write_header(bitstream *const stream, for(p = 0; p < info->nPar; ++p) { - emit_symbol(stream, *(uint64 *)&field->tile[t]. + emit_symbol(stream, *(uint64 *)&codec->tile[t]. parameter[p].info. parameter_min, PREC_BYTE); - emit_symbol(stream, *(uint64 *)&field->tile[t]. + emit_symbol(stream, *(uint64 *)&codec->tile[t]. parameter[p].info. parameter_max, PREC_BYTE); - field->tile[t].parameter[p].info.parameter_max = -FLT_MAX; - field->tile[t].parameter[p].info.parameter_min = FLT_MAX; + codec->tile[t].parameter[p].info.parameter_max = -FLT_MAX; + codec->tile[t].parameter[p].info.parameter_min = FLT_MAX; } } } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar sequence_packets(bwc_field *const field, bwc_field *const field) ! +! FUNCTION NAME: uchar sequence_packets(bwc_codec *const codec, bwc_tile *const tile) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -299,7 +288,7 @@ codestream_write_header(bitstream *const stream, ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! +! codec bwc_codec* - Structure defining the compression/ ! ! decompression stage. ! ! ! ! tile bwc_tile* - Structure defining a bwc tile. ! @@ -319,7 +308,7 @@ codestream_write_header(bitstream *const stream, ! ! \*----------------------------------------------------------------------------------------------------------*/ static uchar -sequence_packets(bwc_field *const field, bwc_tile *const tile) +sequence_packets(bwc_codec *const codec, bwc_tile *const tile) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -347,8 +336,8 @@ sequence_packets(bwc_field *const field, bwc_tile *const tile) ! sequence structure to temporary variables to make the ! ! code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; + control = &codec->control; + info = &codec->info; packet_sequence = tile->packet_sequence; @@ -490,7 +479,7 @@ sequence_packets(bwc_field *const field, bwc_tile *const tile) } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar sequence_packets(bwc_field *const field, bwc_field *const field) ! +! FUNCTION NAME: ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -501,16 +490,11 @@ sequence_packets(bwc_field *const field, bwc_tile *const tile) ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! tile bwc_tile* - Structure defining a bwc tile. ! ! ! ! RETURN VALUE: ! ! ------------- ! ! Type Description ! ! ---- ----------- ! -! uchar - Returns an unsigned char for error handling. ! ! ! ! DEVELOPMENT HISTORY: ! ! -------------------- ! @@ -521,7 +505,7 @@ sequence_packets(bwc_field *const field, bwc_tile *const tile) ! ! \*----------------------------------------------------------------------------------------------------------*/ static void -assemble_tile(bwc_field *const field, bwc_tile *const tile, bitstream *const stream) +assemble_tile(bwc_codec *const codec, bwc_tile *const tile, bitstream *const stream) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -537,7 +521,7 @@ assemble_tile(bwc_field *const field, bwc_tile *const tile, bitstream *const str /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(tile); assert(stream); @@ -546,7 +530,7 @@ assemble_tile(bwc_field *const field, bwc_tile *const tile, bitstream *const str ! sequence structure to temporary variables to make the ! ! code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; emit_symbol(stream, SOT, 2); emit_symbol(stream, 14, 2); @@ -613,14 +597,14 @@ assemble_tile(bwc_field *const field, bwc_tile *const tile, bitstream *const str ! - Patrick Vogler B87D120 V 0.1.0 function created ! ! ! \*----------------------------------------------------------------------------------------------------------*/ -bwc_field* -parse_main_header(bwc_data *const data,bitstream *const stream) +bwc_codec* +parse_main_header(bwc_codec *const codec, bwc_stream *const data, bitstream *const stream) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ uint64 buff_long, buffX, buffY, buffZ, buffTS; - uint64 nX, nY, nZ; + uint64 nX, nY, nZ, nTS; uint32 buff; uint32 bitrate; uint32 Lsax; @@ -629,35 +613,34 @@ parse_main_header(bwc_data *const data,bitstream *const stream) uint16 CSsgc; uint16 Linf, Lctr, Lcom, Leoh, Lunk; uint16 marker; - uint16 nTS; uint8 index, l; uint8 nPar, p; - uint8 codec_prec, precision; + bwc_precision data_prec, codec_prec; /*-----------------------*\ ! DEFINE CHAR VARIABLES: ! \*-----------------------*/ - char* buffer_char; char status; /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - bwc_field *field; bwc_gl_ctrl *control; bwc_gl_inf *info; /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ + assert(codec); assert(data); assert(stream); /*--------------------------------------------------------*\ - ! Save the data info structure to a temporary variable to ! - ! make the code more readable. ! + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! \*--------------------------------------------------------*/ - info = &data->info; + info = &codec->info; + control = &codec->control; status = CODESTREAM_OK; index = 0; @@ -708,41 +691,23 @@ parse_main_header(bwc_data *const data,bitstream *const stream) break; } - info->nX = nX = get_symbol(stream, 8); - info->nY = nY = get_symbol(stream, 8); - info->nZ = nZ = get_symbol(stream, 8); - info->nTS = nTS = (uint16)get_symbol(stream, 2); - info->nPar = nPar = (uint8)get_symbol(stream, 1); - info->precision = codec_prec = (uint8)get_symbol(stream, 1); + nX = get_symbol(stream, 8); + nY = get_symbol(stream, 8); + nZ = get_symbol(stream, 8); + nTS = get_symbol(stream, 8); + nPar = (uint8)get_symbol(stream, 1); + data_prec = (bwc_precision)get_symbol(stream, 1); + codec_prec = (bwc_precision)get_symbol(stream, 1); - buffer_char = (char*)get_chunck(stream, 10); - strncpy(info->f_ext, buffer_char, sizeof(buffer_char)/sizeof(*buffer_char)); - free(buffer_char); + info->codec_prec = codec_prec; - for(p = 0; p < nPar; ++p) - { - buffer_char = (char*)get_chunck(stream, 24); - precision = (uint8)get_symbol(stream, 1); - - bwc_add_param(data, buffer_char, precision); - - free(buffer_char); - } - - field = bwc_initialize_field(data); - if(!field) + configure_codec(codec, nX, nY, nZ, nTS, nPar, data_prec); + if(!codec) { status |= CODESTREAM_ERROR; break; } - /*--------------------------------------------------------*\ - ! Save the global control and info structure to temporary ! - ! variables to make the code more readable. ! - \*--------------------------------------------------------*/ - info = field->info = &data->info; - control = &field->control; - control->codestreamSize = stream->Lmax; status |= CODESTREAM_SGI_READ; @@ -755,7 +720,7 @@ parse_main_header(bwc_data *const data,bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -766,7 +731,7 @@ parse_main_header(bwc_data *const data,bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -777,14 +742,14 @@ parse_main_header(bwc_data *const data,bitstream *const stream) buff_long = get_symbol(stream, 1); if(CSsgc & (0x01 << 0)) { - bwc_set_error_resilience(field); + bwc_set_error_resilience(codec); } buff_long = get_symbol(stream, 1); if(CSsgc & (0x01 << 1)) { - set_quant_style(field, (bwc_quant_st)buff_long); + set_quant_style(codec, (bwc_quant_st)buff_long); } buff_long = get_symbol(stream, 1); @@ -800,50 +765,50 @@ parse_main_header(bwc_data *const data,bitstream *const stream) buff_long = get_symbol(stream, 1); if(CSsgc & (0x01 << 3)) { - set_progression(field, (uint8)buff_long); + set_progression(codec, (uint8)buff_long); } buff_long = get_symbol(stream, 1); if(CSsgc & (0x01 << 4)) { - set_kernels(field, (uint8)(0x03 & (buff_long >> 6)), (uint8)(0x03 & (buff_long >> 4)), + set_kernels(codec, (uint8)(0x03 & (buff_long >> 6)), (uint8)(0x03 & (buff_long >> 4)), (uint8)(0x03 & (buff_long >> 2)), (uint8)(0x03 & buff_long)); } buff_long = get_symbol(stream, 4); if(CSsgc & (0x01 << 5)) { - bwc_set_decomp(field, (uint8)(0xFF & (buff_long >> 24)), (uint8)(0xFF & (buff_long >> 16)), + bwc_set_decomp(codec, (uint8)(0xFF & (buff_long >> 24)), (uint8)(0xFF & (buff_long >> 16)), (uint8)(0xFF & (buff_long >> 8)), (uint8)(0xFF & buff_long)); } buff_long = get_symbol(stream, 2); if(CSsgc & (0x01 << 6)) { - bwc_set_precincts(field, (uint8)(0x0F & (buff_long >> 8)), (uint8)(0x0F & (buff_long >> 12)), + bwc_set_precincts(codec, (uint8)(0x0F & (buff_long >> 8)), (uint8)(0x0F & (buff_long >> 12)), (uint8)(0x0F & buff_long), (uint8)(0x0F & (buff_long >> 4))); } buff_long = get_symbol(stream, 4); if(CSsgc & (0x01 << 7)) { - bwc_set_codeblocks(field, (uint8)(0xFF & (buff_long >> 24)), (uint8)(0xFF & (buff_long >> 16)), + bwc_set_codeblocks(codec, (uint8)(0xFF & (buff_long >> 24)), (uint8)(0xFF & (buff_long >> 16)), (uint8)(0xFF & (buff_long >> 8)), (uint8)(0xFF & buff_long)); } buff_long = get_symbol(stream, 1); if(CSsgc & (0x01 << 8)) { - bwc_set_qm(field, (uint8)buff_long); + bwc_set_qm(codec, (uint8)buff_long); } buffX = get_symbol(stream, 8); buffY = get_symbol(stream, 8); buffZ = get_symbol(stream, 8); - buffTS = get_symbol(stream, 2); + buffTS = get_symbol(stream, 8); if(CSsgc & (0x01 << 9)) { - bwc_set_tiles(field, buffX, buffY, buffZ, (uint16)buffTS, bwc_tile_sizeof); + bwc_set_tiles(codec, buffX, buffY, buffZ, buffTS, bwc_tile_sizeof); } control->nLayers = get_symbol(stream, 1); @@ -852,7 +817,7 @@ parse_main_header(bwc_data *const data,bitstream *const stream) { // memory allocation error fprintf(stderr, MEMERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status|= CODESTREAM_ERROR; break; } @@ -863,10 +828,10 @@ parse_main_header(bwc_data *const data,bitstream *const stream) control->bitrate[l] = *(float *)&bitrate; } - create_field(field); - if(!field) + create_codec(codec); + if(!codec) { - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -881,7 +846,7 @@ parse_main_header(bwc_data *const data,bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -891,17 +856,17 @@ parse_main_header(bwc_data *const data,bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } - data->codestream.aux = calloc(1, sizeof(bwc_stream)); + data->codestream.aux = calloc(1, sizeof(bwc_span)); if(!data->codestream.aux) { // memory allocation error fprintf(stderr, MEMERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -919,7 +884,7 @@ parse_main_header(bwc_data *const data,bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -929,17 +894,17 @@ parse_main_header(bwc_data *const data,bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } - data->codestream.com = calloc(1, sizeof(bwc_stream)); + data->codestream.com = calloc(1, sizeof(bwc_span)); if(!data->codestream.com) { // memory allocation error fprintf(stderr, MEMERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -947,7 +912,7 @@ parse_main_header(bwc_data *const data,bitstream *const stream) data->codestream.com->memory = get_chunck(stream, Lcom - 2); data->codestream.com->size = Lcom -2; - status |= CODESTREAM_ERROR; + status |= CODESTREAM_COM_READ; break; } @@ -959,7 +924,7 @@ parse_main_header(bwc_data *const data,bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -969,12 +934,12 @@ parse_main_header(bwc_data *const data,bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } - if(codec_prec == 8) + if(codec_prec == bwc_precision_double) { /*--------------------------------------------------------*\ ! Loop through all tile parameters and... ! @@ -988,14 +953,14 @@ parse_main_header(bwc_data *const data,bitstream *const stream) ! header stream. ! \*--------------------------------------------------------*/ buff_long = get_symbol(stream, sizeof(double)); - field->tile[t].parameter[p].info.parameter_min = (bwc_float)*(double*)&buff_long; + codec->tile[t].parameter[p].info.parameter_min = (bwc_float)*(double*)&buff_long; buff_long = get_symbol(stream, sizeof(double)); - field->tile[t].parameter[p].info.parameter_max = (bwc_float)*(double*)&buff_long; + codec->tile[t].parameter[p].info.parameter_max = (bwc_float)*(double*)&buff_long; } } } - else if(codec_prec == 4) + else if(codec_prec == bwc_precision_single) { /*--------------------------------------------------------*\ ! Loop through all tile parameters and... ! @@ -1009,20 +974,20 @@ parse_main_header(bwc_data *const data,bitstream *const stream) ! header stream. ! \*--------------------------------------------------------*/ buff = get_symbol(stream, sizeof(float)); - field->tile[t].parameter[p].info.parameter_min = (bwc_float)*(float*)&buff; + codec->tile[t].parameter[p].info.parameter_min = (bwc_float)*(float*)&buff; buff = get_symbol(stream, sizeof(float)); - field->tile[t].parameter[p].info.parameter_max = (bwc_float)*(float*)&buff; + codec->tile[t].parameter[p].info.parameter_max = (bwc_float)*(float*)&buff; } } } - return field; + return codec; } else { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; } break; @@ -1034,7 +999,7 @@ parse_main_header(bwc_data *const data,bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -1044,7 +1009,7 @@ parse_main_header(bwc_data *const data,bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -1059,7 +1024,7 @@ parse_main_header(bwc_data *const data,bitstream *const stream) } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar sequence_packets(bwc_field *const field, bwc_field *const field) ! +! FUNCTION NAME: ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -1070,16 +1035,11 @@ parse_main_header(bwc_data *const data,bitstream *const stream) ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! tile bwc_tile* - Structure defining a bwc tile. ! ! ! ! RETURN VALUE: ! ! ------------- ! ! Type Description ! ! ---- ----------- ! -! uchar - Returns an unsigned char for error handling. ! ! ! ! DEVELOPMENT HISTORY: ! ! -------------------- ! @@ -1090,7 +1050,7 @@ parse_main_header(bwc_data *const data,bitstream *const stream) ! ! \*----------------------------------------------------------------------------------------------------------*/ static uchar -parse_tile(bwc_field *const field, bitstream *const stream) +parse_tile(bwc_codec *const codec, bitstream *const stream) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -1110,7 +1070,7 @@ parse_tile(bwc_field *const field, bitstream *const stream) /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(stream); /*--------------------------------------------------------*\ @@ -1118,7 +1078,7 @@ parse_tile(bwc_field *const field, bitstream *const stream) ! sequence structure to temporary variables to make the ! ! code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; if(!can_read(stream, 2)) { @@ -1144,7 +1104,7 @@ parse_tile(bwc_field *const field, bitstream *const stream) return 1; } - tile = &field->tile[buf]; + tile = &codec->tile[buf]; tile->control.body_size = body_size = (uint64)get_symbol(stream, 8); @@ -1160,7 +1120,7 @@ parse_tile(bwc_field *const field, bitstream *const stream) ! Sequence the packets according to the user specified op- ! ! tion. ! \*--------------------------------------------------------*/ - if(sequence_packets(field, tile)) + if(sequence_packets(codec, tile)) { return 1; } @@ -1198,7 +1158,7 @@ parse_tile(bwc_field *const field, bitstream *const stream) packet->header.memory = get_access(stream); - if(parse_packet(field, tile, packet, body_size)) + if(parse_packet(codec, tile, packet, body_size)) { return 1; } @@ -1240,7 +1200,7 @@ parse_tile(bwc_field *const field, bitstream *const stream) ! ! \*----------------------------------------------------------------------------------------------------------*/ static uchar -parse_body(bwc_field *const field, bitstream *const stream) +parse_body(bwc_codec *const codec, bitstream *const stream) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -1256,7 +1216,7 @@ parse_body(bwc_field *const field, bitstream *const stream) /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); status = CODESTREAM_OK; @@ -1274,7 +1234,7 @@ parse_body(bwc_field *const field, bitstream *const stream) { case SOT: { - if(parse_tile(field, stream)) + if(parse_tile(codec, stream)) { status |= CODESTREAM_ERROR; } @@ -1307,7 +1267,7 @@ parse_body(bwc_field *const field, bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -1317,7 +1277,7 @@ parse_body(bwc_field *const field, bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -1336,7 +1296,7 @@ parse_body(bwc_field *const field, bitstream *const stream) || || \************************************************************************************************************/ /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: bwc_stream* assemble_codestream(bwc_field *const field) ! +! FUNCTION NAME: bwc_span* assemble_codestream(bwc_codec *const codec, bwc_stream *const data) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -1347,14 +1307,14 @@ parse_body(bwc_field *const field, bitstream *const stream) ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! +! codec bwc_codec* - Structure defining the compression/ ! ! decompression stage. ! ! ! ! RETURN VALUE: ! ! ------------- ! ! Type Description ! ! ---- ----------- ! -! bwc_stream* - Packed stream containing the compressed data set. ! +! bwc_span* - Packed stream containing the compressed data set. ! ! ! ! DEVELOPMENT HISTORY: ! ! -------------------- ! @@ -1364,12 +1324,13 @@ parse_body(bwc_field *const field, bitstream *const stream) ! 13.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! ! ! \*----------------------------------------------------------------------------------------------------------*/ -bwc_stream* -assemble_codestream(bwc_field *const field) +size_t +assemble_codestream(bwc_codec *const codec, bwc_stream *const data) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ + size_t compressed_size; uint64 i; /*-----------------------*\ @@ -1378,12 +1339,12 @@ assemble_codestream(bwc_field *const field) bwc_gl_ctrl *control; bwc_tile *tile; bitstream *stream; - bwc_stream *packed_stream; /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); + assert(data); /*--------------------------------------------------------*\ ! Save the global control and info structure to temporary ! @@ -1391,7 +1352,7 @@ assemble_codestream(bwc_field *const field) ! the final codestream size with the number of header ! ! bytes. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; control->codestreamSize = control->headerSize + 2; @@ -1405,15 +1366,15 @@ assemble_codestream(bwc_field *const field) ! Save the tile structure in a temporary variable to make ! ! the code more readable. ! \*--------------------------------------------------------*/ - tile = &field->tile[i]; + tile = &codec->tile[i]; /*--------------------------------------------------------*\ ! Sequence the packets according to the user specified op- ! ! tion and iterate the size of the codestream. ! \*--------------------------------------------------------*/ - if(sequence_packets(field, tile)) + if(sequence_packets(codec, tile)) { - return NULL; + return 0; } control->codestreamSize += tile->control.header_size + tile->control.body_size; @@ -1423,8 +1384,8 @@ assemble_codestream(bwc_field *const field) ! Initialize the final codestream and emit the header ! ! bytes. ! \*--------------------------------------------------------*/ - stream = init_stream(NULL, control->codestreamSize, 'c'); - codestream_write_header(stream, field); + stream = init_bitstream(data->out, control->codestreamSize, 'c'); + codestream_write_header(stream, codec, data); /*--------------------------------------------------------*\ ! Walk through the tile structure and assemble the packed ! @@ -1437,33 +1398,21 @@ assemble_codestream(bwc_field *const field) ! Save the tile structure in a temporary variable to make ! ! the code more readable. ! \*--------------------------------------------------------*/ - tile = &field->tile[i]; + tile = &codec->tile[i]; - assemble_tile(field, tile, stream); + assemble_tile(codec, tile, stream); } emit_symbol(stream, EOC, 2); - packed_stream = calloc(1, sizeof(bwc_stream)); - if(!packed_stream) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return NULL; - } + compressed_size = stream->L; + free(stream); - if(terminate_stream(stream, packed_stream)) - { - return NULL; - } - else - { - return packed_stream; - } + return compressed_size; } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar parse_codestream(bwc_field *const field, bitstream *const stream) ! +! FUNCTION NAME: uchar parse_codestream(bwc_codec *const codec, bitstream *const stream) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -1474,7 +1423,7 @@ assemble_codestream(bwc_field *const field) ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! +! codec bwc_codec* - Structure defining the compression/ ! ! decompression stage. ! ! ! ! stream bitstream* - Structure used to assemble a bwc bit- ! @@ -1494,32 +1443,32 @@ assemble_codestream(bwc_field *const field) ! 05.08.2019 Patrick Vogler B87D120 V 0.1.0 function created ! ! ! \*----------------------------------------------------------------------------------------------------------*/ -bwc_field* -parse_codestream(bwc_data *const data, uint8 const layer) +bwc_codec* +parse_codestream(bwc_codec *const codec, bwc_stream *const data, uint8 const layer) { /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - bwc_field *field; bitstream *stream; /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ assert(data); + assert(codec); /*--------------------------------------------------------*\ ! Initialize a bitstream used to parse the packed code- ! ! stream. ! \*--------------------------------------------------------*/ - stream = init_stream(data->codestream.data->memory, 10, 'd'); + stream = init_bitstream(data->inp, 10, 'd'); /*--------------------------------------------------------*\ - ! Parse the main header and set up the field structure for ! + ! Parse the main header and set up the codec structure for ! ! the current decompression run. ! \*--------------------------------------------------------*/ - field = parse_main_header(data, stream); - if(!field) + parse_main_header(codec, data, stream); + if(!codec) { return NULL; } @@ -1528,36 +1477,36 @@ parse_codestream(bwc_data *const data, uint8 const layer) ! Initialize the useLayer option to decompress the entire ! ! codestream. ! \*--------------------------------------------------------*/ - field->control.useLayer = field->control.nLayers - 1; + codec->control.useLayer = codec->control.nLayers - 1; /*--------------------------------------------------------*\ ! Check if the layer index supplied by the function caller ! ! is valid. ! \*--------------------------------------------------------*/ - if(layer < field->control.nLayers && layer > 0) + if(layer < codec->control.nLayers && layer > 0) { /*--------------------------------------------------------*\ ! Amend the use layer variable in the global control struc-! ! ture. ! \*--------------------------------------------------------*/ - field->control.useLayer = layer; + codec->control.useLayer = layer; } /*--------------------------------------------------------*\ ! Parse the rest of the compressed codestream and load the ! - ! body into the field structure. ! + ! body into the codec structure. ! \*--------------------------------------------------------*/ - if(parse_body(field, stream)) + if(parse_body(codec, stream)) { - bwc_kill_compression(field); + bwc_free_codec(codec); return NULL; } /*--------------------------------------------------------*\ ! Free the bitstream used to parse the codestream and re- ! - ! turn the field structure to the function caller. ! + ! turn the codec structure to the function caller. ! \*--------------------------------------------------------*/ free(stream); - return field; -} \ No newline at end of file + return codec; +} diff --git a/src/library/dwt.c b/src/library/dwt.c index b22c7f2..c280e0d 100755 --- a/src/library/dwt.c +++ b/src/library/dwt.c @@ -1421,7 +1421,7 @@ initialize_gain_lut() } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: bwc_float get_dwt_energy_gain(bwc_field *const field, uchar highband_flag, uint16 level) ! +! FUNCTION NAME: bwc_float get_dwt_energy_gain(bwc_codec *const codec, uchar highband_flag, uint16 level) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -1434,7 +1434,7 @@ initialize_gain_lut() ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! +! codec bwc_codec* - Structure defining the compression/ ! ! decompression stage. ! ! ! ! highband_flag uchar - Defines the subband for which Gb is ! @@ -1459,7 +1459,7 @@ initialize_gain_lut() ! ! \*----------------------------------------------------------------------------------------------------------*/ bwc_float -get_dwt_energy_gain(bwc_field *const field, uchar highband_flag, uint16 level) +get_dwt_energy_gain(bwc_codec *const codec, uchar highband_flag, uint16 level) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -1480,15 +1480,15 @@ get_dwt_energy_gain(bwc_field *const field, uchar highband_flag, uint16 level) /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); - assert(level <= field->control.nDecomp + 1); + assert(codec); + assert(level <= codec->control.nDecomp + 1); assert(highband_flag <= DIM_ALL); /*--------------------------------------------------------*\ ! Save the global control structure to a temporary varia- ! ! ble to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; /*--------------------------------------------------------*\ ! Evaluate the number of decompositions in each temporal & ! @@ -1576,7 +1576,7 @@ get_dwt_energy_gain(bwc_field *const field, uchar highband_flag, uint16 level) } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar forward_discrete_wavelet_transform(bwc_field *const field, ! +! FUNCTION NAME: uchar forward_discrete_wavelet_transform(bwc_codec *const codec, ! ! -------------- bwc_parameter *const parameter) ! ! ! ! DESCRIPTION: ! @@ -1594,7 +1594,7 @@ get_dwt_energy_gain(bwc_field *const field, uchar highband_flag, uint16 level) ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! +! codec bwc_codec* - Structure defining the compression/ ! ! decompression stage. ! ! ! ! parameter bwc_parameter* - Structure defining a bwc parameter. ! @@ -1614,28 +1614,22 @@ get_dwt_energy_gain(bwc_field *const field, uchar highband_flag, uint16 level) ! ! \*----------------------------------------------------------------------------------------------------------*/ uchar -forward_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter) +forward_wavelet_transform(bwc_codec *const codec, bwc_parameter *const parameter) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ - uint64 incr_X, incr_Y, incr_Z; - uint64 rX0, rY0, rZ0; - uint64 rX1, rY1, rZ1; - uint64 width, height, depth; - uint64 x, y, z; + uint64 incr_X, incr_Y, incr_Z, incr_TS; + uint64 rX0, rY0, rZ0, rTS0; + uint64 rX1, rY1, rZ1, rTS1; + uint64 width, height, depth, dt; + uint64 x, y, z, t; int64 nThreads; int16 i; uint32 buff_size; - uint16 incr_TS; - uint16 rTS0; - uint16 rTS1; - uint16 dt; - uint16 t; - uint8 id; uint8 filter_tapsX, filter_tapsY, filter_tapsZ; uint8 filter_tapsTS; @@ -1652,7 +1646,7 @@ forward_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(parameter); /*-----------------------*\ @@ -1670,7 +1664,7 @@ forward_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter ! Save the global control and parameter info structure to ! ! temporary variables to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; param_info = ¶meter->info; /*--------------------------------------------------------*\ @@ -1777,8 +1771,8 @@ forward_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter rY1 = (uint64)parameter->resolution[control->nDecomp - level].info.Y1; rZ0 = (uint64)parameter->resolution[control->nDecomp - level].info.Z0; rZ1 = (uint64)parameter->resolution[control->nDecomp - level].info.Z1; - rTS0 = (uint16)parameter->resolution[control->nDecomp - level].info.TS0; - rTS1 = (uint16)parameter->resolution[control->nDecomp - level].info.TS1; + rTS0 = (uint64)parameter->resolution[control->nDecomp - level].info.TS0; + rTS1 = (uint64)parameter->resolution[control->nDecomp - level].info.TS1; if(level < control->decompX && (rX1 - rX0) > 1) { @@ -2117,7 +2111,7 @@ forward_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar inverse_discrete_wavelet_transform(bwc_field *const field, ! +! FUNCTION NAME: uchar inverse_discrete_wavelet_transform(bwc_codec *const codec, ! ! -------------- bwc_parameter *const parameter) ! ! ! ! DESCRIPTION: ! @@ -2135,7 +2129,7 @@ forward_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! +! codec bwc_codec* - Structure defining the compression/ ! ! decompression stage. ! ! ! ! parameter bwc_parameter* - Structure defining a bwc parameter. ! @@ -2155,28 +2149,22 @@ forward_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter ! ! \*----------------------------------------------------------------------------------------------------------*/ uchar -inverse_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter) +inverse_wavelet_transform(bwc_codec *const codec, bwc_parameter *const parameter) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ - uint64 incr_X, incr_Y, incr_Z; - uint64 rX0, rY0, rZ0; - uint64 rX1, rY1, rZ1; - uint64 width, height, depth; - uint64 x, y, z; + uint64 incr_X, incr_Y, incr_Z, incr_TS; + uint64 rX0, rY0, rZ0, rTS0; + uint64 rX1, rY1, rZ1, rTS1; + uint64 width, height, depth, dt; + uint64 x, y, z, t; int64 nThreads; int64 i; uint32 buff_size; - uint16 incr_TS; - uint16 rTS0; - uint16 rTS1; - uint16 dt; - uint16 t; - uint8 id; uint8 filter_tapsX, filter_tapsY, filter_tapsZ; uint8 filter_tapsTS; @@ -2193,7 +2181,7 @@ inverse_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(parameter); /*-----------------------*\ @@ -2211,7 +2199,7 @@ inverse_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter ! Save the global control and parameter info structure to ! ! temporary variables to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; param_info = ¶meter->info; /*--------------------------------------------------------*\ @@ -2318,8 +2306,8 @@ inverse_wavelet_transform(bwc_field *const field, bwc_parameter *const parameter rY1 = (uint64)parameter->resolution[control->nDecomp - level].info.Y1; rZ0 = (uint64)parameter->resolution[control->nDecomp - level].info.Z0; rZ1 = (uint64)parameter->resolution[control->nDecomp - level].info.Z1; - rTS0 = (uint16)parameter->resolution[control->nDecomp - level].info.TS0; - rTS1 = (uint16)parameter->resolution[control->nDecomp - level].info.TS1; + rTS0 = (uint64)parameter->resolution[control->nDecomp - level].info.TS0; + rTS1 = (uint64)parameter->resolution[control->nDecomp - level].info.TS1; if(level < control->decompTS && (rTS1 - rTS0) > 1) { diff --git a/src/library/libbwc.c b/src/library/libbwc.c index 7917322..1d66076 100755 --- a/src/library/libbwc.c +++ b/src/library/libbwc.c @@ -78,23 +78,17 @@ || | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || || || \************************************************************************************************************/ -/*----------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function takes an integer value and generates a version with the appropri- ! -! ate byte unit in log2 format that is returned to the function caller. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 03.05.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ #ifdef BWC_PROFILE +/*================================================================================================*/ +/** + * @details Takes an integer value and generates a version with the appropriate byte unit in + * log2 format as return value string. + * + * @param[in] integer Integer value of bytes. + * + * @retval const char* + */ +/*================================================================================================*/ const char* get_size(uint64_t integer) { @@ -144,43 +138,22 @@ } #endif -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uint8 initialize_precinct(bwc_field *const field, bwc_precinct *precinct, ! -! -------------- const uint32 dX, const uint32 dY, ! -! const uint32 dZ, const uint32 dTS) ! -! ! -! ! -! DESCRIPTION: ! -! ------------ ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! precinct bwc_precinct* - Structure defining a bwc precinct. ! -! ! -! dX, dY, dZ, dTS unsigned int(32 bit) - Defines the offset of the codeblock ! -! with regards to the current subband. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! unsigned int (8 bit) - Subband gain factor in log2 factor. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 24.05.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Initializes the precinct layout. + * + * @param[in] codec Structure defining the (de)compression codec. + * @param[inout] precinct Structure defining the precinct. + * @param[in] dX Codeblock offset with regard to the current subband in the 1st dimension. + * @param[in] dY Codeblock offset with regard to the current subband in the 2nd dimension. + * @param[in] dZ Codeblock offset with regard to the current subband in the 3rd dimension. + * @param[in] dTS Codeblock offset with regard to the current subband in the 4th dimension. + * + * @retval uint8_t + */ +/*================================================================================================*/ static uint8 -initialize_precinct(bwc_field *const field, bwc_precinct *precinct, const uint32 dX, const uint32 dY, +initialize_precinct(bwc_codec *const codec, bwc_precinct *precinct, const uint32 dX, const uint32 dY, const uint32 dZ, const uint32 dTS) { /*-----------------------*\ @@ -202,7 +175,7 @@ initialize_precinct(bwc_field *const field, bwc_precinct *precinct, const uint32 /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(precinct); /*--------------------------------------------------------*\ @@ -210,7 +183,7 @@ initialize_precinct(bwc_field *const field, bwc_precinct *precinct, const uint32 ! and info structure to temporary variables to make the ! ! code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; prec_control = &precinct->control; prec_info = &precinct->info; @@ -314,11 +287,11 @@ initialize_precinct(bwc_field *const field, bwc_precinct *precinct, const uint32 cblk_info->X0 = dX + (uint32)MAX(prec_info->X0 , cbSizeX * (cb_X + (uint32)floor((float)prec_info->X0 / cbSizeX ))); cblk_info->Y0 = dY + (uint32)MAX(prec_info->Y0 , cbSizeY * (cb_Y + (uint32)floor((float)prec_info->Y0 / cbSizeY ))); cblk_info->Z0 = dZ + (uint32)MAX(prec_info->Z0 , cbSizeZ * (cb_Z + (uint32)floor((float)prec_info->Z0 / cbSizeZ ))); - cblk_info->TS0 = dTS + (uint16)MAX(prec_info->TS0, cbSizeTS * (cb_TS + (uint32)floor((float)prec_info->TS0/ cbSizeTS))); + cblk_info->TS0 = dTS + (uint32)MAX(prec_info->TS0, cbSizeTS * (cb_TS + (uint32)floor((float)prec_info->TS0/ cbSizeTS))); cblk_info->X1 = dX + (uint32)MIN(prec_info->X1 , cbSizeX * (cb_X + (uint32)floor((float)prec_info->X0 / cbSizeX ) + 1)); cblk_info->Y1 = dY + (uint32)MIN(prec_info->Y1 , cbSizeY * (cb_Y + (uint32)floor((float)prec_info->Y0 / cbSizeY ) + 1)); cblk_info->Z1 = dZ + (uint32)MIN(prec_info->Z1 , cbSizeZ * (cb_Z + (uint32)floor((float)prec_info->Z0 / cbSizeZ ) + 1)); - cblk_info->TS1 = dTS + (uint16)MIN(prec_info->TS1, cbSizeTS * (cb_TS + (uint32)floor((float)prec_info->TS0/ cbSizeTS) + 1)); + cblk_info->TS1 = dTS + (uint32)MIN(prec_info->TS1, cbSizeTS * (cb_TS + (uint32)floor((float)prec_info->TS0/ cbSizeTS) + 1)); } } } @@ -327,38 +300,17 @@ initialize_precinct(bwc_field *const field, bwc_precinct *precinct, const uint32 return 0; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uint8 subband_gain(const uint8 highband_flag) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function calculates the gain for a specific subband in log2 format according to the ! -! number of applied 1-D wavelet transforms. The subband gain is calculated by evaluating the ! -! hamming weight of the highband flag. (see https://en.wikipedia.org/wiki/Hamming_weight) ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! highband_flag unsigned in (8 bit) - Flag defining the number and types of ! -! 1-D wavelet of transforms applied to ! -! the subband. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! unsigned int (8 bit) - Subband gain factor in log2 factor. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 15.05.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Calculates the gain for a specific subband in log2 format according to the number of + * applied 1-D wavelet transforms. The subband gain is calculated by evaluating the + * hamming weight of the highband flag. (see https://en.wikipedia.org/wiki/Hamming_weight) + * + * @param[in] highband_flag Number and types of transforms applied to the subband. + * + * @retval uint8_t Subband gain factor in log2 factor. + */ +/*================================================================================================*/ static uint8 subband_gain(const uint8 highband_flag) { /*-----------------------*\ @@ -385,55 +337,22 @@ static uint8 subband_gain(const uint8 highband_flag) return (temp + (temp >> 4)) & 0x0F; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar initialize_subband(bwc_field *const field, bwc_parameter *const parameter, ! -! -------------- bwc_resolution *const resolution, ! -! bwc_subband *const subband, ! -! int32 resolution_level, ! -! int16 highband_flag) ! -! ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function initializes the bwc_subband structure with all necessary standard parameters ! -! to (de)compress a floating point array with nX * nY * nZ grid points, nTS timesteps and ! -! nPar parameters. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! parameter bwc_parameter* - Structure defining a bwc tile parameter.! -! ! -! resolution bwc_resolution* - Structure defining a bwc resolution ! -! level. ! -! ! -! subband bwc_subband* - Structure defining a bwc subband. ! -! ! -! resolution_level signed int(32 bit) - Defines the current resolution level. ! -! ! -! highband_flag signed int(16 bit) - Defines the type of highband the cur- ! -! rent subband represents. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! uchar - Returns an unsigned char for error handling. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 12.12.2017 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Initializes the bwc_subband structure. + * + * @param[in] codec Structure defining the (de)compression codec. + * @param[in] parameter Data of given parameter/field. + * @param[in] resolution Structure defining the resolution level. + * @param[in] subband Structure defining te subband. + * @param[in] resolution_level Current resolution level index. + * @param[in] highband_flag Type of highband that the current subband represents. + * + * @retval unsigned char + */ +/*================================================================================================*/ static uchar -initialize_subband(bwc_field *const field, bwc_parameter *const parameter, bwc_resolution *const resolution, +initialize_subband(bwc_codec *const codec, bwc_parameter *const parameter, bwc_resolution *const resolution, bwc_subband *const subband, int32 resolution_level, int16 highband_flag) @@ -464,10 +383,10 @@ initialize_subband(bwc_field *const field, bwc_parameter *const parameter, bwc_r /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(resolution); assert(subband); - assert(resolution_level <= field->control.nDecomp + 1); + assert(resolution_level <= codec->control.nDecomp + 1); assert(highband_flag <= DIM_ALL); /*--------------------------------------------------------*\ @@ -475,7 +394,7 @@ initialize_subband(bwc_field *const field, bwc_parameter *const parameter, bwc_r ! trol and info structures to temporary variables to make ! ! the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; param_control = ¶meter->control; param_info = ¶meter->info; @@ -506,11 +425,11 @@ initialize_subband(bwc_field *const field, bwc_parameter *const parameter, bwc_r subb_info->X0 = (uint64)ceil( ((float)param_info->X0 / (1 << level_X)) - 0.5 * ((highband_flag & DIM_X) >> 0)); subb_info->Y0 = (uint64)ceil( ((float)param_info->Y0 / (1 << level_Y)) - 0.5 * ((highband_flag & DIM_Y) >> 1)); subb_info->Z0 = (uint64)ceil( ((float)param_info->Z0 / (1 << level_Z)) - 0.5 * ((highband_flag & DIM_Z) >> 2)); - subb_info->TS0 = (uint16)ceil( ((float)param_info->TS0 / (1 << level_TS)) - 0.5 * ((highband_flag & DIM_TS) >> 3)); + subb_info->TS0 = (uint64)ceil( ((float)param_info->TS0 / (1 << level_TS)) - 0.5 * ((highband_flag & DIM_TS) >> 3)); subb_info->X1 = (uint64)ceil( ((float)param_info->X1 / (1 << level_X)) - 0.5 * ((highband_flag & DIM_X) >> 0)); subb_info->Y1 = (uint64)ceil( ((float)param_info->Y1 / (1 << level_Y)) - 0.5 * ((highband_flag & DIM_Y) >> 1)); subb_info->Z1 = (uint64)ceil( ((float)param_info->Z1 / (1 << level_Z)) - 0.5 * ((highband_flag & DIM_Z) >> 2)); - subb_info->TS1 = (uint16)ceil( ((float)param_info->TS1 / (1 << level_TS)) - 0.5 * ((highband_flag & DIM_TS) >> 3)); + subb_info->TS1 = (uint64)ceil( ((float)param_info->TS1 / (1 << level_TS)) - 0.5 * ((highband_flag & DIM_TS) >> 3)); /*--------------------------------------------------------*\ ! Evaluate the dynamic range (Rb) of the current subband. ! @@ -523,7 +442,7 @@ initialize_subband(bwc_field *const field, bwc_parameter *const parameter, bwc_r ! band. ! \*--------------------------------------------------------*/ subb_control->highband_flag = highband_flag; - subb_info->dwt_gain = get_dwt_energy_gain(field, highband_flag, decomp_level); + subb_info->dwt_gain = get_dwt_energy_gain(codec, highband_flag, decomp_level); /*--------------------------------------------------------*\ ! Evaluate the quantization exponent, mantissa, step size ! @@ -632,11 +551,11 @@ initialize_subband(bwc_field *const field, bwc_parameter *const parameter, bwc_r prec_info->X0 = (uint32)MAX(res_info->X0 , pSizeX * (p_X + (uint32)floor(res_info->X0 / pSizeX))); prec_info->Y0 = (uint32)MAX(res_info->Y0 , pSizeY * (p_Y + (uint32)floor(res_info->Y0 / pSizeY))); prec_info->Z0 = (uint32)MAX(res_info->Z0 , pSizeZ * (p_Z + (uint32)floor(res_info->Z0 / pSizeZ))); - prec_info->TS0 = (uint16)MAX(res_info->TS0, pSizeTS * (p_TS + (uint32)floor(res_info->TS0/ pSizeTS))); + prec_info->TS0 = (uint32)MAX(res_info->TS0, pSizeTS * (p_TS + (uint32)floor(res_info->TS0/ pSizeTS))); prec_info->X1 = (uint32)MIN(res_info->X1 , pSizeX * (p_X + (uint32)floor(res_info->X0 / pSizeX) + 1)); prec_info->Y1 = (uint32)MIN(res_info->Y1 , pSizeY * (p_Y + (uint32)floor(res_info->Y0 / pSizeY) + 1)); prec_info->Z1 = (uint32)MIN(res_info->Z1 , pSizeZ * (p_Z + (uint32)floor(res_info->Z0 / pSizeZ) + 1)); - prec_info->TS1 = (uint16)MIN(res_info->TS1, pSizeTS * (p_TS + (uint32)floor(res_info->TS0/ pSizeTS)+ 1)); + prec_info->TS1 = (uint32)MIN(res_info->TS1, pSizeTS * (p_TS + (uint32)floor(res_info->TS0/ pSizeTS)+ 1)); if((control->nDecomp - control->decompX) < resolution_level) { @@ -658,15 +577,15 @@ initialize_subband(bwc_field *const field, bwc_parameter *const parameter, bwc_r if((control->nDecomp - control->decompTS) < resolution_level) { - prec_info->TS0 = (uint16) ceil(((float)prec_info->TS0 / 2) - 0.5 * ((highband_flag & DIM_TS) >> 3)); - prec_info->TS1 = (uint16) ceil(((float)prec_info->TS1 / 2) - 0.5 * ((highband_flag & DIM_TS) >> 3)); + prec_info->TS0 = (uint32) ceil(((float)prec_info->TS0 / 2) - 0.5 * ((highband_flag & DIM_TS) >> 3)); + prec_info->TS1 = (uint32) ceil(((float)prec_info->TS1 / 2) - 0.5 * ((highband_flag & DIM_TS) >> 3)); } /*--------------------------------------------------------*\ ! Initialize the precinct structure according to the speci-! ! fied compression parameters. ! \*--------------------------------------------------------*/ - initialize_precinct(field, &subband->precinct[p], (uint32)sb_sX - subb_info->X0, (uint32)sb_sY - subb_info->Y0, + initialize_precinct(codec, &subband->precinct[p], (uint32)sb_sX - subb_info->X0, (uint32)sb_sY - subb_info->Y0, (uint32)sb_sZ - subb_info->Z0, (uint32)sb_sTS - subb_info->TS0); /*--------------------------------------------------------*\ @@ -682,59 +601,22 @@ initialize_subband(bwc_field *const field, bwc_parameter *const parameter, bwc_r return 0; } - -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void fill_buffer(bwc_field *const field, bwc_tile *const tile, ! -! ------------ bwc_parameter *const parameter, ! -! bwc_sample *const working_buffer, ! -! double *const data, ! -! uint64 param_size, ! -! uint16 param_id) ! -! ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function is used to fill the working buffer with the appropriate flow field data for ! -! the specified tile parameter. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! tile bwc_tile* - Structure defining a bwc tile. ! -! ! -! parameter bwc_parameter* - Structure defining a bwc parameter. ! -! ! -! working_buffer bwc_sample* - Working buffer used to store flow field ! -! data for a specific tile parameter. ! -! ! -! param_size uint64 - Specifies the byte size of one tile ! -! parameter. ! -! ! -! parameter uint16 - Specifies the parameter index for the ! -! current tile parameter. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 22.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Fills the working buffer with the flow field data before compression. + * + * @param[in] codec Structure defining the (de)compression codec. + * @param[in] tile Structure defining a bwc tile. + * @param[in] parameter Data of given parameter/field. + * @param[inout] working_buffer Buffer which stores the flow field for compression. + * @param[in] data Instance of bwc_stream type with the flow field data. + * @param[in] param_id Parameter index for the current tile parameter. + */ +/*================================================================================================*/ static void -fill_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const parameter, +fill_buffer(bwc_codec *const codec, bwc_tile *const tile, bwc_parameter *const parameter, bwc_sample *const working_buffer, - bwc_data *const data, + bwc_stream *const data, uint16 param_id) { /*-----------------------*\ @@ -742,8 +624,7 @@ fill_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const p \*-----------------------*/ uint64 width, height, depth, dt; uint64 param_offset; - uint64 x, y, z; - uint16 t; + uint64 x, y, z, t; /*-----------------------*\ ! DEFINE FLOAT VARIABLES: ! @@ -760,12 +641,11 @@ fill_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const p bwc_tile_inf *tile_info; bwc_param_ctrl *param_control; bwc_param_inf *param_info; - bwc_cmd_opts_ll *param; /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(tile); assert(parameter); assert(working_buffer); @@ -776,7 +656,7 @@ fill_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const p ! structures to temporary variables to make the code more ! ! readable. ! \*--------------------------------------------------------*/ - info = field->info; + info = &codec->info; tile_info = &tile->info; @@ -787,17 +667,7 @@ fill_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const p ! Calculate the offset of the current parameter in the da- ! ! ta array. ! \*--------------------------------------------------------*/ - param_offset = 0; - param = data->info.parameter->root; - - while(param != NULL && param->id < param_id) - { - if(param->precision == param_info->precision) - { - param_offset += param->size; - } - param = param -> next; - } + param_offset = info->nX * info->nY * info->nZ * info->nTS * param_id; /*--------------------------------------------------------*\ ! Associate the working buffer with the data pointer in ! @@ -824,13 +694,13 @@ fill_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const p ! Check if the parameter is single or double precision and ! ! handle the field accordingly. ! \*--------------------------------------------------------*/ - if(param_info->precision == 8) + if(info->data_prec == bwc_precision_double) { /*--------------------------------------------------------*\ ! Safe the field pointer to a temporary variable to make ! ! the code more readable. ! \*--------------------------------------------------------*/ - tmp_d = data->field.d; + tmp_d = (double *)data->inp; /*--------------------------------------------------------*\ ! Walk through the tile parameter working buffer. ! @@ -878,7 +748,7 @@ fill_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const p ! Safe the field pointer to a temporary variable to make ! ! the code more readable. ! \*--------------------------------------------------------*/ - tmp_f = data->field.f; + tmp_f = (float *)data->inp; /*--------------------------------------------------------*\ ! Walk through the tile parameter working buffer. ! @@ -936,57 +806,22 @@ fill_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const p param_control->beta = 2.0f/(param_info->parameter_max - param_info->parameter_min); } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void fill_buffer(bwc_field *const field, bwc_tile *const tile, ! -! ------------ bwc_parameter *const parameter, ! -! bwc_sample *const working_buffer, ! -! double *const data, ! -! uint64 param_size, ! -! uint16 param_id) ! -! ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function is used to flush the working buffer to the flow field data memory block. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! tile bwc_tile* - Structure defining a bwc tile. ! -! ! -! parameter bwc_parameter* - Structure defining a bwc parameter. ! -! ! -! working_buffer bwc_sample* - Working buffer used to store flow field ! -! data for a specific tile parameter. ! -! ! -! param_size uint64 - Specifies the byte size of one tile ! -! parameter. ! -! ! -! parameter uint16 - Specifies the parameter index for the ! -! current tile parameter. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 22.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Flushes the working buffer to the flow field data memory block after decompression. + * + * @param[in] codec Structure defining the (de)compression codec. + * @param[in] tile Structure defining a bwc tile. + * @param[in] parameter Data of given parameter/field. + * @param[in] working_buffer Buffer which stores the flow field during decompression. + * @param[inout] data Instance of bwc_stream type that the flow field data is flushed to. + * @param[in] param_id Parameter index for the current tile parameter. + */ +/*================================================================================================*/ static void -flush_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const parameter, +flush_buffer(bwc_codec *const codec, bwc_tile *const tile, bwc_parameter *const parameter, bwc_sample *const working_buffer, - bwc_data *const data, + bwc_stream *const data, uint16 param_id) { /*-----------------------*\ @@ -995,8 +830,7 @@ flush_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const uint64 width, height, depth, dt; uint64 nX, nY, nZ; uint64 param_offset; - uint64 x, y, z; - uint16 t; + uint64 x, y, z, t; /*-----------------------*\ ! DEFINE FLOAT VARIABLES: ! @@ -1010,12 +844,11 @@ flush_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const bwc_sample *src; bwc_gl_inf *info; bwc_param_inf *param_info; - bwc_cmd_opts_ll *param; /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(tile); assert(parameter); assert(working_buffer); @@ -1026,7 +859,7 @@ flush_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const ! structures to temporary variables to make the code more ! ! readable. ! \*--------------------------------------------------------*/ - info = field->info; + info = &codec->info; param_info = ¶meter->info; @@ -1038,17 +871,7 @@ flush_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const ! Calculate the offset of the current parameter in the da- ! ! ta array. ! \*--------------------------------------------------------*/ - param_offset = 0; - param = data->info.parameter->root; - - while(param != NULL && param->id < param_id) - { - if(param->precision == param_info->precision) - { - param_offset += param->size; - } - param = param -> next; - } + param_offset = info->nX * info->nY * info->nZ * info->nTS * param_id; /*--------------------------------------------------------*\ ! Calculate the width, height, depth and dt of the current ! @@ -1063,13 +886,13 @@ flush_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const ! Check if the parameter is single or double precision and ! ! handle the field accordingly. ! \*--------------------------------------------------------*/ - if(param_info->precision == 8) + if(info->data_prec == bwc_precision_double) { /*--------------------------------------------------------*\ ! Safe the field pointer to a temporary variable to make ! ! the code more readable. ! \*--------------------------------------------------------*/ - tmp_d = data->field.d; + tmp_d = (double *)data->out; /*--------------------------------------------------------*\ ! Walk through the tile parameter working buffer. ! @@ -1111,7 +934,7 @@ flush_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const ! Safe the field pointer to a temporary variable to make ! ! the code more readable. ! \*--------------------------------------------------------*/ - tmp_f = data->field.f; + tmp_f = (float *)data->out; /*--------------------------------------------------------*\ ! Walk through the tile parameter working buffer. ! @@ -1149,45 +972,20 @@ flush_buffer(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const } } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void buff_normalize(bwc_field *const field, bwc_parameter *const parameter) ! -! ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function is used to normalize the values v[i] of the current tile parameter to the ! -! range of [-1, 1) and scale them to a desired dynamic range: ! -! ! -! q[i] = [(v[i] - α)/β] * 2^Qm. ! -! ! -! Here, α and β define the normalization constants and Qm represents the dynamic range of ! -! the Q number format. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! parameter bwc_parameter* - Structure defining a bwc parameter. ! -! ! -! working_buffer bwc_sample* - Working buffer used to store flow field ! -! data for a specific tile parameter. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 24.10.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Used to normalize the values v[i] of the current tile parameter to the range of [-1, 1) + * and scale them to a desired dynamic range: + * q[i] = [(v[i] - α)/β] * 2^Qm. + * Here, α and β define the normalization constants and Qm represents the dynamic range + * of the Q number format. + * + * @param[inout] codec Structure defining the (de)compression codec. + * @param[in] parameter Data of given parameter/field. + */ +/*================================================================================================*/ static void -normalize_param(bwc_field *const field, bwc_parameter *const parameter) +normalize_param(bwc_codec *const codec, bwc_parameter *const parameter) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -1220,7 +1018,7 @@ normalize_param(bwc_field *const field, bwc_parameter *const parameter) ! info structures to temporary variables to make the code ! ! more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; param_control = ¶meter->control; param_info = ¶meter->info; @@ -1274,45 +1072,20 @@ normalize_param(bwc_field *const field, bwc_parameter *const parameter) } } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void denormalize_param(bwc_field *const field, bwc_parameter *const parameter) ! -! ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function is used to scale the decompressed values to their original dynamic range and ! -! denormalize the flow field values. ! -! ! -! q[i] = [(v[i]/2^Qm) * β] + α. ! -! ! -! Here, α and β define the normalization constants and Qm represents the dynamic range of ! -! the Q number format. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! parameter bwc_parameter* - Structure defining a bwc parameter. ! -! ! -! working_buffer bwc_sample* - Working buffer used to store flow field ! -! data for a specific tile parameter. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 24.10.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Used to scale the decompressed values to their original dynamic range and denormalize + * the flow field values. + * q[i] = [(v[i]/2^Qm) * β] + α. + * Here, α and β define the normalization constants and Qm represents the dynamic range + * of the Q number format. + * + * @param[inout] codec Structure defining the (de)compression codec. + * @param[in] parameter Data of given parameter/field. + */ +/*================================================================================================*/ static void -denormalize_param(bwc_field *const field, bwc_parameter *const parameter) +denormalize_param(bwc_codec *const codec, bwc_parameter *const parameter) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -1344,7 +1117,7 @@ denormalize_param(bwc_field *const field, bwc_parameter *const parameter) ! tures to temporary variables to make the code more ! ! readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; param_info = ¶meter->info; @@ -1397,207 +1170,93 @@ denormalize_param(bwc_field *const field, bwc_parameter *const parameter) } } +/*================================================================================================*/ +/** + * @details Allocates an instance of type bwc_codec with the compile-time codec precision. + * + * @retval bwc_stream* + */ +/*================================================================================================*/ +bwc_codec* +alloc_codec() +{ + /*--------------------------------------------------------*\ + ! Allocate the root compression data structure. ! + \*--------------------------------------------------------*/ + bwc_codec *codec = calloc(1, sizeof(bwc_codec)); + if(!codec) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return NULL; + } + + /*--------------------------------------------------------*\ + ! Save the codec precision in the info structure. ! + \*--------------------------------------------------------*/ +#if PREC_BYTE == 8 + codec->info.codec_prec = bwc_precision_double; +#elif PREC_BYTE == 4 + codec->info.codec_prec = bwc_precision_single; +#endif + + return codec; +} + /************************************************************************************************************\ || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || || | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || || || \************************************************************************************************************/ -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: bwc_field *bwc_initialize_data(...) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function initializes the bwc_data structure with all necessary parameters. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! nX ,nY, nZ unsigned int(64 bit) - Number of spatial Datapoints ! -! ! -! nTS unsigned int(16 bit) - Number of Timesteps. ! -! ! -! nPar unsigned int(8 bit) - Number of Parameters ! -! ! -! file_extension char* - File extension associated ! -! with the numerical dataset. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! bwc_data* - Structure used to store a numerical ! -! dataset/compressed bitstream. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 09.06.2021 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ -bwc_data* -bwc_initialize_data(double* field, uint64 const nX, uint64 const nY, uint64 const nZ, uint16 const nTS, uint8 const nPar, char *file_extension) +/*================================================================================================*/ +/** + * @details Allocates and assigns user-owned pointers for (de)compression input and output. + * + * @param[in] inpbuf Input data. Can be compressed or original flow field data. + * @param[in] outbuf Output pointer which must have enough space for given output. + * @param[in] mode Decides the mode to be input for compression or decompression (comp | decomp). + * + * @retval bwc_stream* + */ +/*================================================================================================*/ +bwc_stream* +bwc_init_stream(void *const inpbuf, void *const outbuf, bwc_mode const mode) { /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - bwc_gl_inf *info; - bwc_data *file; + bwc_stream *stream; - file = calloc(1, sizeof(bwc_data)); - if(!file) + stream = calloc(1, sizeof(bwc_stream)); + if(!stream) { // memory allocation error fprintf(stderr, MEMERROR); return NULL; } - info = &file->info; + stream->inp = inpbuf; + stream->out = outbuf; + stream->mode = mode; - info->nX = nX; - info->nY = nY; - info->nZ = nZ; - info->nTS = nTS; - info->nPar = nPar; - memcpy(&info->f_ext, file_extension, sizeof(char) * 19); - - file->field.d = field; - - return file; + return stream; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void bwc_add_param(bwc_data* data, char *name, uint16 sample, uchar dim, uint8 precision) ! -! -------------- ! -! ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function initializes and adds new parameters to the parameter linked list. The linked ! -! list stores the parameter name, its precision, sampling factor and the dimension for which ! -! the sampling is active. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! name char* - Name of parameter(id). ! -! ! -! sample unsigned int(16 bit) - Sampling factor for parameter(id). ! -! ! -! dim unsigned char - Dimension(s) for which the sampling ! -! factor is active. ! -! ! -! precision unsigned int(8 bit) - Bit precision of the parameter. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 19.10.2017 Patrick Vogler B87D120 V 0.1.0 function created ! -! 03.12.2019 Patrick Vogler B87E7E4 V 0.1.0 redefined the function for the ! -! bwc_data structure. ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ -void -bwc_add_param(bwc_data* data, char *name, uint8 precision) -{ - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_gl_inf *info; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(data); - - /*--------------------------------------------------------*\ - ! Save the global info structure to a temporary variable ! - ! to make the code more readable. ! - \*--------------------------------------------------------*/ - info = &data->info; - - /*--------------------------------------------------------*\ - ! Check if the specified parameter name has the proper ! - ! length. ! - \*--------------------------------------------------------*/ - if((strlen(name) > 24) && name) - { - fprintf(stderr, "o==========================================================o\n"\ - "| WARNING: Invalid parameter name: %-24s|\n"\ - "| |\n"\ - "| Parameter names cannot exceed 24 characters. |\n"\ - "| |\n"\ - "o==========================================================o\n",name); - } - - /*--------------------------------------------------------*\ - ! Check if the parameter structure has already been allo- ! - ! cated. ! - \*--------------------------------------------------------*/ - if(info->parameter == NULL) - { - /*--------------------------------------------------------*\ - ! If the bwc_add_param function is called for the first ! - ! time, allocate the parameter structure and save the root ! - ! node address. ! - \*--------------------------------------------------------*/ - info->parameter = calloc(1, sizeof(bwc_cmd_opts_ll)); - info->parameter->root = info->parameter; - } - else - { - /*--------------------------------------------------------*\ - ! If a new parameter is added, allocate the nex linked ! - ! list node, save the root node address in its structure ! - ! and set the linked list access pointer to the new node. ! - \*--------------------------------------------------------*/ - info->parameter->next = calloc(1, sizeof(bwc_cmd_opts_ll)); - info->parameter->next->root = info->parameter->root; - info->parameter->next->id = info->parameter->id + 1; - info->parameter = info->parameter->next; - } - - /*--------------------------------------------------------*\ - ! Save the name of the new parameter its precision in the ! - ! structure of the new node. ! - \*--------------------------------------------------------*/ - strcpy(info->parameter->name, name ? name : "undefined"); - info->parameter->precision = precision ? precision : PREC_BYTE; - - /*--------------------------------------------------------*\ - ! Evaluate the parameter size the information in the ! - ! linked list. ! - \*--------------------------------------------------------*/ - info->parameter->size = (info->nX * info->nY * info->nZ * info->nTS); -} - -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: ! -! -------------- ! -! ! -! ! -! DESCRIPTION: ! -! ------------ ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Amends a user-defined comment in the bwc_codec structure. Can be used to comment the + * compressed data with user-defined information that helps data interpretation. + * + * @param[inout] codec Structure defining the compression coder. + * @param[in] com Commentary string. + * @param[in] size Size of commentary string. + * + * @retval unsigned char + */ +/*================================================================================================*/ uchar -bwc_set_com(bwc_data *const data, char const *const com, uint16 size) +bwc_set_com(bwc_stream *const data, char const *const com, uint16 size) { /*-----------------------*\ ! DEFINE ASSERTIONS: ! @@ -1609,8 +1268,9 @@ bwc_set_com(bwc_data *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); @@ -1625,17 +1285,20 @@ bwc_set_com(bwc_data *const data, char const *const com, uint16 size) return 0; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: ! -! -------------- ! -! ! -! ! -! DESCRIPTION: ! -! ------------ ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Amends the auxiliary information in the bwc_codec structure. Can be used to store and + * retrieve file format specific metadata. + * + * @param[inout] codec Structure defining the compression coder. + * @param[in] aux Auxiliary information string. + * @param[in] size Size of auxiliary information string. + * + * @retval unsigned char + */ +/*================================================================================================*/ uchar -bwc_set_aux(bwc_data *const data, char const *const aux, uint32 size) +bwc_set_aux(bwc_stream *const data, char const *const aux, uint32 size) { /*-----------------------*\ ! DEFINE ASSERTIONS: ! @@ -1647,193 +1310,34 @@ bwc_set_aux(bwc_data *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; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: bwc_field *bwc_initialize_data(...) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function is used to copy the numerical dataset stored in the bwc_data ! -! structure to a user supplied memory block. A size argument is necessary ! -! to verify that the memory block has the correct size. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! data bwc_data* - Structure used to store a numerical ! -! dataset/compressed bitstream. ! -! ! -! buffer unsigned char* - Memory block supplied by ! -! the function caller. ! -! ! -! data bwc_data* - Size of memory block. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 09.06.2021 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ -void -bwc_get_data(bwc_data* data, uchar* buffer, uint64 size) -{ - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - - if(size != (uint64)(data->info.nX * data->info.nY * data->info.nZ * data->info.nTS * data->info.nPar)) - { - fprintf(stderr, "Incorrect buffer size\n"); - } - else - { - memcpy(buffer, data->field.d, size * sizeof(double)); - } -} - -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void bwc_free_data(bwc_data* file) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function deallocates the data structure used to store an numerical dataset/compressed ! -! and can be called if an error occurs or once the data is no longer needed is to be closed. ! -! The deallocation will be carried out down to the structure levels that have been allocated. ! -! ! -! PARAMETERS: ! -! ----------- ! -! ! -! Variable Type Description ! -! -------- ---- ----------- ! -! file bwc_data - Defines a structure used to store all ! -! the relevant parameters and the data ! -! field of a numerical dataset or com- ! -! pressed codestream. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! ! -! Variable Type Description ! -! -------- ---- ----------- ! -! - - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! 04.12.2019 Patrick Vogler B87E7E4 V 0.1.0 -! ! -\*----------------------------------------------------------------------------------------------------------*/ -void -bwc_free_data(bwc_data* data) -{ - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_cmd_opts_ll *param, *temp; - - if(data) - { - if(data->info.parameter) - { - param = data->info.parameter->root; - - while(param != NULL) - { - temp = param; - param = param -> next; - free(temp); - } - } - - if(data) - { - if(data->codestream.data) - { - release_packed_stream(data->codestream.data); - } - if(data->codestream.aux) - { - release_packed_stream(data->codestream.aux); - } - if(data->codestream.com) - { - release_packed_stream(data->codestream.com); - } - if(data->fp) - { - fclose(data->fp); - } - free(data->codestream.data); - free(data->codestream.aux); - free(data->codestream.com); - free(data->field.d); - free(data->field.f); - free(data); - } - } -} - -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar create_field(bwc_field *const field) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function creates the field structure used to (de)compress a floating point array de- ! -! fined by the bwc_initialize function. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! unsigned char - Returns an unsigned char for error handling. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Creates intrinsics like tile and subband structure in a valid codec instance. + * + * @param[inout] codec Structure defining the compression coder. + * + * @retval unsigned char + */ +/*================================================================================================*/ uchar -create_field(bwc_field *const field) +create_codec(bwc_codec *const codec) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -1856,7 +1360,6 @@ create_field(bwc_field *const field) \*-----------------------*/ bwc_gl_ctrl *control; bwc_gl_inf *info; - bwc_cmd_opts_ll *param; bwc_parameter *parameter; bwc_param_ctrl *param_control; bwc_param_inf *param_info; @@ -1871,14 +1374,14 @@ create_field(bwc_field *const field) /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); /*--------------------------------------------------------*\ ! Save the global control and info structure to temporary ! ! variables to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; + control = &codec->control; + info = &codec->info; /*--------------------------------------------------------*\ ! Calculate the number of tiles in all spatial and tempo- ! @@ -1890,8 +1393,8 @@ create_field(bwc_field *const field) num_tiles_Z = (int)ceil(((float)info->nZ / control->tileSizeZ)); num_tiles_TS = (int)ceil(((float)info->nTS/ control->tileSizeTS)); - field->tile = calloc(control->nTiles, sizeof(bwc_tile)); - if(!field->tile) + codec->tile = calloc(control->nTiles, sizeof(bwc_tile)); + if(!codec->tile) { // memory allocation error fprintf(stderr, MEMERROR); @@ -1921,7 +1424,7 @@ create_field(bwc_field *const field) ! Save the tile and its info and control structure to tem- ! ! porary variables to make the code more readable. ! \*--------------------------------------------------------*/ - tile = &field->tile[i]; + tile = &codec->tile[i]; tile_control = &tile->control; tile_info = &tile->info; @@ -1936,11 +1439,11 @@ create_field(bwc_field *const field) tile_info->X0 = (uint64)MAX(0, x * control->tileSizeX); tile_info->Y0 = (uint64)MAX(0, y * control->tileSizeY); tile_info->Z0 = (uint64)MAX(0, z * control->tileSizeZ); - tile_info->TS0 = (uint16)MAX(0, t * control->tileSizeTS); + tile_info->TS0 = (uint64)MAX(0, t * control->tileSizeTS); tile_info->X1 = (uint64)MIN(info->nX , (x + 1) * control->tileSizeX); tile_info->Y1 = (uint64)MIN(info->nY , (y + 1) * control->tileSizeY); tile_info->Z1 = (uint64)MIN(info->nZ , (z + 1) * control->tileSizeZ); - tile_info->TS1 = (uint16)MIN(info->nTS, (t + 1) * control->tileSizeTS); + tile_info->TS1 = (uint64)MIN(info->nTS, (t + 1) * control->tileSizeTS); /*--------------------------------------------------------*\ ! Initialize the tile header size. ! @@ -1965,23 +1468,8 @@ create_field(bwc_field *const field) return 1; } - /*--------------------------------------------------------*\ - ! Initialize the parameter information linked listed. ! - \*--------------------------------------------------------*/ - param = info->parameter->root; - for(j = 0; j < info->nPar; ++j) { - /*--------------------------------------------------------*\ - ! Check if there is a node in the parameter information ! - ! linked list corresponding to the current paramter. ! - \*--------------------------------------------------------*/ - if(!param && (param->id == j)) - { - fprintf(stderr, MEMERROR); - return 1; - } - /*--------------------------------------------------------*\ ! Save the parameter and its info and control structure to ! ! temporary variables to make the code more readable. ! @@ -1990,13 +1478,6 @@ create_field(bwc_field *const field) param_control = ¶meter->control; param_info = ¶meter->info; - /*--------------------------------------------------------*\ - ! Save the corresponding parameter name and its sampling ! - ! factors and precision in the info and control structures.! - \*--------------------------------------------------------*/ - param_info->name = param->name; - param_info->precision = param->precision; - /*--------------------------------------------------------*\ ! Initialize the number of codeblocks for the current ! ! parameter. ! @@ -2053,11 +1534,11 @@ create_field(bwc_field *const field) res_info->X0 = (uint64)ceil((float)param_info->X0 / (1 << MIN(control->nDecomp -r, control->decompX))); res_info->Y0 = (uint64)ceil((float)param_info->Y0 / (1 << MIN(control->nDecomp -r, control->decompY))); res_info->Z0 = (uint64)ceil((float)param_info->Z0 / (1 << MIN(control->nDecomp -r, control->decompZ))); - res_info->TS0 = (uint16)ceil((float)param_info->TS0/ (1 << MIN(control->nDecomp -r, control->decompTS))); + res_info->TS0 = (uint64)ceil((float)param_info->TS0/ (1 << MIN(control->nDecomp -r, control->decompTS))); res_info->X1 = (uint64)ceil((float)param_info->X1 / (1 << MIN(control->nDecomp -r, control->decompX))); res_info->Y1 = (uint64)ceil((float)param_info->Y1 / (1 << MIN(control->nDecomp -r, control->decompY))); res_info->Z1 = (uint64)ceil((float)param_info->Z1 / (1 << MIN(control->nDecomp -r, control->decompZ))); - res_info->TS1 = (uint16)ceil((float)param_info->TS1/ (1 << MIN(control->nDecomp -r, control->decompTS))); + res_info->TS1 = (uint64)ceil((float)param_info->TS1/ (1 << MIN(control->nDecomp -r, control->decompTS))); /*--------------------------------------------------------*\ ! Calculate the number of precincts to cover tile t in pa- ! @@ -2154,7 +1635,7 @@ create_field(bwc_field *const field) { if(r == 0 || ((l & highband_flag) == l && l != 0)) { - if(initialize_subband(field, parameter, resolution, &resolution->subband[m], r, l)) + if(initialize_subband(codec, parameter, resolution, &resolution->subband[m], r, l)) { return 1; } @@ -2199,12 +1680,6 @@ create_field(bwc_field *const field) } } } - - /*--------------------------------------------------------*\ - ! Advance the parameter information linked listed to the ! - ! next node. ! - \*--------------------------------------------------------*/ - param = param->next; } /*--------------------------------------------------------*\ @@ -2235,41 +1710,15 @@ create_field(bwc_field *const field) return 0; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void kill_compression(bwc_field *const field) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function deallocates the compression field structure used to define and control the ! -! bwc codec and can be called if an error occurs during the (de-)compression stage or once ! -! the codec has finished. The deallocation will be carried out down to the structure levels ! -! that have been allocated. ! -! ! -! PARAMETERS: ! -! ----------- ! -! ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 19.10.2017 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Deallocates the (de)compression codec structure and contained resources. + * + * @param[inout] codec Structure defining the compression coder. + */ +/*================================================================================================*/ void -bwc_kill_compression(bwc_field *const field) +bwc_free_codec(bwc_codec *const codec) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -2285,109 +1734,94 @@ bwc_kill_compression(bwc_field *const field) bwc_gl_ctrl *control; bwc_gl_inf *info; - if(field) + if(codec) { /*--------------------------------------------------------*\ ! Save the global control and info structure to temporary ! ! variables to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; + control = &codec->control; + info = &codec->info; - if(field->tile) + if(codec->tile) { for(i = 0; i < control->nTiles; ++i) { - if(field->tile[i].parameter) + if(codec->tile[i].parameter) { for(j = 0; j < info->nPar; ++j) { - if(field->tile[i].parameter[j].resolution) + if(codec->tile[i].parameter[j].resolution) { for(r = 0; r < control->nDecomp + 1; ++r) { - if(field->tile[i].parameter[j].resolution[r].subband) + if(codec->tile[i].parameter[j].resolution[r].subband) { - for(l = 0; l < field->tile[i].parameter[j].resolution[r].control.number_of_subbands; ++l) + for(l = 0; l < codec->tile[i].parameter[j].resolution[r].control.number_of_subbands; ++l) { - if(field->tile[i].parameter[j].resolution[r].subband[l].precinct) + if(codec->tile[i].parameter[j].resolution[r].subband[l].precinct) { - for(k = 0; k < field->tile[i].parameter[j].resolution[r].control.number_of_precincts; ++k) + for(k = 0; k < codec->tile[i].parameter[j].resolution[r].control.number_of_precincts; ++k) { - if(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock) + if(codec->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock) { - for(c = 0; c < field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].control.number_of_codeblocks; ++c) + for(c = 0; c < codec->tile[i].parameter[j].resolution[r].subband[l].precinct[k].control.number_of_codeblocks; ++c) { - if(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock[c].encoded_block) + if(codec->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock[c].encoded_block) { - free(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock[c].encoded_block->data); + free(codec->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock[c].encoded_block->data); } - free(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock[c].control.memory); - free(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock[c].encoded_block); + free(codec->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock[c].control.memory); + free(codec->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock[c].encoded_block); } } - if(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].control.number_of_codeblocks) + if(codec->tile[i].parameter[j].resolution[r].subband[l].precinct[k].control.number_of_codeblocks) { - kill_tagtree(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].control.tag_inclusion); - kill_tagtree(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].control.tag_msbs); + kill_tagtree(codec->tile[i].parameter[j].resolution[r].subband[l].precinct[k].control.tag_inclusion); + kill_tagtree(codec->tile[i].parameter[j].resolution[r].subband[l].precinct[k].control.tag_msbs); } - free(field->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock); + free(codec->tile[i].parameter[j].resolution[r].subband[l].precinct[k].codeblock); } } - free(field->tile[i].parameter[j].resolution[r].subband[l].precinct); + free(codec->tile[i].parameter[j].resolution[r].subband[l].precinct); } } - free(field->tile[i].parameter[j].resolution[r].subband); - free(field->tile[i].parameter[j].resolution[r].packet); + free(codec->tile[i].parameter[j].resolution[r].subband); + free(codec->tile[i].parameter[j].resolution[r].packet); } } - free(field->tile[i].parameter[j].resolution); - free(field->tile[i].parameter[j].access); + free(codec->tile[i].parameter[j].resolution); + free(codec->tile[i].parameter[j].access); } } - free(field->tile[i].packet_sequence); - free(field->tile[i].parameter); + free(codec->tile[i].packet_sequence); + free(codec->tile[i].parameter); } } free(control->bitrate); - free(field->tile); - free(field); + free(codec->tile); + free(codec); } } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: bwc_field *bwc_initialize_field(bwc_data *const data) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function initializes the bwc_field structure with all necessary standard parameters ! -! to (de)compress a floating point array with nX * nY * nZ grid points, nTS timesteps and ! -! nPar parameters. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! nX ,nY, nZ unsigned int(64 bit) - Structure used to store a numerical ! -! dataset/compressed bitstream. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! bwc_field* Defines the (de)compression data structure. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ -bwc_field* -bwc_initialize_field(bwc_data *const data) +/*================================================================================================*/ +/** + * @details Configures the bwc_codec structure for compression with given dimensions and precision. + * + * @param[inout] codec Structure defining the compression coder. + * @param[in] nX Field data size in first dimension. + * @param[in] nY Field data size in two dimension. + * @param[in] nZ Field data size in three dimension. + * @param[in] nTS Field data size in fourth dimension. + * @param[in] nPar Number of parameters. + * @param[in] prec Data precision. + * + * @retval bwc_codec* + */ +/*================================================================================================*/ +bwc_codec* +configure_codec(bwc_codec *const codec, uint64 const nX, uint64 const nY, uint64 const nZ, + uint64 const nTS, uint8 const nPar, bwc_precision const prec) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -2406,24 +1840,19 @@ bwc_initialize_field(bwc_data *const data) bwc_gl_ctrl *control; bwc_gl_inf *info; - /*--------------------------------------------------------*\ - ! Allocate the root compression data structure. ! - \*--------------------------------------------------------*/ - bwc_field *field = calloc(1, sizeof(bwc_field)); - if(!field) - { - // memory allocation error - fprintf(stderr, MEMERROR); - bwc_kill_compression(field); - return NULL; - } - /*--------------------------------------------------------*\ ! Save the global control and info structure to temporary ! ! variables to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; - info = field->info = &data->info; + control = &codec->control; + info = &codec->info; + + info->nX = nX; + info->nY = nY; + info->nZ = nZ; + info->nTS = nTS; + info->nPar = nPar; + info->data_prec = prec; /*--------------------------------------------------------*\ ! Set all tile sizes to their maximum allowable value. The ! @@ -2479,11 +1908,6 @@ bwc_initialize_field(bwc_data *const data) control->bitrate = 0; control->guard_bits = 2; - /*--------------------------------------------------------*\ - ! Save the codec precision in the info structure. ! - \*--------------------------------------------------------*/ - info->precision = PREC_BYTE; - /*--------------------------------------------------------*\ ! Calculate the possible decomposition levels for all ! ! spatial and temporal dimensions. ! @@ -2515,7 +1939,7 @@ bwc_initialize_field(bwc_data *const data) \*--------------------------------------------------------*/ if(initialize_gain_lut()) { - bwc_kill_compression(field); + bwc_free_codec(codec); return NULL; } @@ -2525,7 +1949,7 @@ bwc_initialize_field(bwc_data *const data) ! tion (10.19) (epsilon = 6, mu = 16) from JPEG2000 by ! ! by David S. Taubman and Michael W. Marcellin (p.437). ! \*--------------------------------------------------------*/ - delta = (bwc_float)(1/(pow(2, 2 + PREC_BIT) * sqrt(get_dwt_energy_gain(field, 0, control->nDecomp)))); + delta = (bwc_float)(1/(pow(2, 2 + PREC_BIT) * sqrt(get_dwt_energy_gain(codec, 0, control->nDecomp)))); for(control->qt_exponent = 0; delta < 1; ++control->qt_exponent, delta *= 2); control->qt_mantissa = (uint16)floor(0.5f + ((delta - 1.0f) * (1 << 16))); @@ -2549,41 +1973,65 @@ bwc_initialize_field(bwc_data *const data) } } - return field; + return codec; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void bwc_set_error_resilience(bwc_field *const field) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function sets the error resilience marker in the bwc_field structure if an error ! -! resilient compression approach is to be employed. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 13.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Allocates the bwc_codec structure for compression with given dimensions and precision. + * + * @param[in] nX Field data size in first dimension. + * @param[in] nY Field data size in two dimension. + * @param[in] nZ Field data size in three dimension. + * @param[in] nTS Field data size in fourth dimension. + * @param[in] nPar Number of parameters. + * @param[in] prec Data precision. + * + * @retval bwc_codec* + */ +/*================================================================================================*/ +bwc_codec* +bwc_alloc_coder(uint64 const nX, uint64 const nY, uint64 const nZ, uint64 const nTS, + uint8 const nPar, bwc_precision const prec) +{ + /*--------------------------------------------------------*\ + ! Allocate and configure the compression data structure. ! + \*--------------------------------------------------------*/ + bwc_codec *codec = alloc_codec(); + codec = configure_codec(codec, nX, nY, nZ, nTS, nPar, prec); + codec->mode = comp; + + return codec; +} + +/*================================================================================================*/ +/** + * @details Allocates the bwc_codec structure for decompression. + * + * @retval bwc_codec* + */ +/*================================================================================================*/ +bwc_codec* +bwc_alloc_decoder() +{ + /*--------------------------------------------------------*\ + ! Allocate the root compression data structure. ! + \*--------------------------------------------------------*/ + bwc_codec *codec = alloc_codec(); + codec->mode = decomp; + + return codec; +} + +/*================================================================================================*/ +/** + * @details Turns on the error resilience marker in the bwc_codec structure. + * + * @param[inout] codec Structure defining the compression coder. + */ +/*================================================================================================*/ void -bwc_set_error_resilience(bwc_field *const field) +bwc_set_error_resilience(bwc_codec *const codec) { /*-----------------------*\ ! DEFINE STRUCTS: ! @@ -2593,16 +2041,16 @@ bwc_set_error_resilience(bwc_field *const field) /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); /*--------------------------------------------------------*\ ! Save the global control structure to a temporary varia- ! ! ble to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; /*--------------------------------------------------------*\ - ! Amend the codeblock style in the bwc_field structure ! + ! Amend the codeblock style in the bwc_codec structure ! ! according to the specified value. ! \*--------------------------------------------------------*/ control->error_resilience ^= 0x01; @@ -2614,41 +2062,16 @@ bwc_set_error_resilience(bwc_field *const field) control->CSsgc ^= (0x01 << 0); } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void bwc_set_quant_style(bwc_field *const field, bwc_quant_st quantization_style) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function amends the quantization style in the bwc_field structure according to the ! -! specified value. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! quantization_style bwc_quant_st - Quantization style used during compres- ! -! sion. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Amends the quantization style in the bwc_codec structure. + * + * @param[inout] codec Structure defining the compression coder. + * @param[in] quantization_sytle Quantization style employed during compression. + */ +/*================================================================================================*/ void -set_quant_style(bwc_field *const field, bwc_quant_st quantization_style) +set_quant_style(bwc_codec *const codec, bwc_quant_st quantization_style) { /*-----------------------*\ ! DEFINE STRUCTS: ! @@ -2658,17 +2081,17 @@ set_quant_style(bwc_field *const field, bwc_quant_st quantization_style) /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert((quantization_style == bwc_qt_derived) || (quantization_style == bwc_qt_none)); /*--------------------------------------------------------*\ ! Save the global control structure to a temporary varia- ! ! ble to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; /*--------------------------------------------------------*\ - ! Amend the quantization style in the bwc_field structure ! + ! Amend the quantization style in the bwc_codec structure ! ! according to the specified value. ! \*--------------------------------------------------------*/ control->quantization_style = quantization_style; @@ -2680,41 +2103,16 @@ set_quant_style(bwc_field *const field, bwc_quant_st quantization_style) control->CSsgc |= (0x01 << 1); } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void bwc_set_quant_step_size(bwc_field *const field, double delta) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function amends the quantization step size in the bwc_field structure according to ! -! the specified value. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! delta double - Quantization step size used during ! -! compression. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 16.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Amends the quantization step size in the bwc_codec structure. + * + * @param[inout] codec Structure defining the compression coder. + * @param[in] delta Quantization step size employed during compression. + */ +/*================================================================================================*/ void -set_quant_step_size(bwc_field *const field, double delta) +set_quant_step_size(bwc_codec *const codec, double delta) { /*-----------------------*\ ! DEFINE STRUCTS: ! @@ -2724,13 +2122,13 @@ set_quant_step_size(bwc_field *const field, double delta) /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); /*--------------------------------------------------------*\ ! Save the global control structure to a temporary varia- ! ! ble to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; /*--------------------------------------------------------*\ ! Check if the quantization step size lies within the ac- ! @@ -2738,15 +2136,14 @@ set_quant_step_size(bwc_field *const field, 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; } @@ -2784,42 +2181,16 @@ set_quant_step_size(bwc_field *const field, double delta) control->CSsgc |= (0x01 << 2); } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void bwc_set_progression(bwc_field *const field, bwc_prog_ord progression) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function amends the progression order in the bwc_field structure according to the ! -! specified value. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! progression bwc_prog_ord - Progression orders employed during com- ! -! pression (CPRL, LRCP, PCRL, RLCP, ! -! RPCL). ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Amends the progression order in the bwc_codec structure. + * + * @param[inout] codec Structure defining the compression coder. + * @param[in] progression Progression orders employed during compression. + */ +/*================================================================================================*/ void -set_progression(bwc_field *const field, bwc_prog_ord progression) +set_progression(bwc_codec *const codec, bwc_prog_ord progression) { /*-----------------------*\ ! DEFINE STRUCTS: ! @@ -2829,7 +2200,7 @@ set_progression(bwc_field *const field, bwc_prog_ord progression) /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert((progression == bwc_prog_CPRL) || (progression == bwc_prog_LRCP) || (progression == bwc_prog_PCRL) || (progression == bwc_prog_RLCP) || (progression == bwc_prog_RPCL)); @@ -2838,10 +2209,10 @@ set_progression(bwc_field *const field, bwc_prog_ord progression) ! Save the global control structure to a temporary varia- ! ! ble to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; /*--------------------------------------------------------*\ - ! Amend the progression order in the bwc_field structure ! + ! Amend the progression order in the bwc_codec structure ! ! according to the specified value. ! \*--------------------------------------------------------*/ control->progression = progression; @@ -2853,46 +2224,19 @@ set_progression(bwc_field *const field, bwc_prog_ord progression) control->CSsgc |= (0x01 << 3); } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void bwc_set_kernels(bwc_field *const field, bwc_dwt_filter KernelX, ! -! -------------- bwc_dwt_filter KernelY, ! -! bwc_dwt_filter KernelZ, ! -! bwc_dwt_filter KernelTS) ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function amends the wavelet kernels in the bwc_field structure according to the ! -! specified values. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! KernelX, KernelY, KernelZ bwc_dwt_filter - Wavelet kernels used for spatial ! -! decomposition. ! -! ! -! KernelT bwc_dwt_filter - Wavelet kernel used for temporal ! -! decomposition. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Amends the wavelet kernels in the bwc_codec structure. + * + * @param[inout] codec Structure defining the compression coder. + * @param[in] KernelX Wavelet kernel used in first dimemsion in log2 exponent format. + * @param[in] KernelY Wavelet kernel used in first dimemsion in log2 exponent format. + * @param[in] KernelZ Wavelet kernel used in third dimemsion in log2 exponent format. + * @param[in] KernelTS Wavelet kernel used in fourth dimemsion in log2 exponent format. + */ +/*================================================================================================*/ void -set_kernels(bwc_field *const field, bwc_dwt_filter KernelX, bwc_dwt_filter KernelY, +set_kernels(bwc_codec *const codec, bwc_dwt_filter KernelX, bwc_dwt_filter KernelY, bwc_dwt_filter KernelZ, bwc_dwt_filter KernelTS) { /*-----------------------*\ @@ -2903,16 +2247,16 @@ set_kernels(bwc_field *const field, bwc_dwt_filter KernelX, bwc_dwt_filter Kerne /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); /*--------------------------------------------------------*\ ! Save the global control structure to a temporary varia- ! ! ble to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; /*--------------------------------------------------------*\ - ! Amend the wavelet kernels in the bwc_field structure ac- ! + ! Amend the wavelet kernels in the bwc_codec structure ac- ! ! cording to the specified values. For all unspecified ! ! (NULL) values the corresponding wavelet kernel is set to ! ! bwc_dwt_9_7/bwc_dwt_haar. ! @@ -2929,44 +2273,19 @@ set_kernels(bwc_field *const field, bwc_dwt_filter KernelX, bwc_dwt_filter Kerne control->CSsgc |= (0x01 << 4); } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void bwc_set_decomp(bwc_field *const field, uint8 decompX, uint8 decompY, ! -! -------------- uint8 decompZ, uint8 decompTS) ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function amends the decomposition levels in the bwc_field structure according to the ! -! specified values. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! decompX, decompY, decompZ unsigned int(8 bit) - Number of spatial wavelet decomposition ! -! levels used during compression. ! -! ! -! decompTS unsigned int(8 bit) - Number of temporal wavelet decomposi- ! -! tion level used during compression. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Amends the decomposition levels in the bwc_codec structure. + * + * @param[inout] codec Structure defining the compression coder. + * @param[in] decompX Number of wavelet decomposition levels in first dimemsion in log2 exponent format. + * @param[in] decompY Number of wavelet decomposition levels in first dimemsion in log2 exponent format. + * @param[in] decompZ Number of wavelet decomposition levels in third dimemsion in log2 exponent format. + * @param[in] decompTS Number of wavelet decomposition levels in fourth dimemsion in log2 exponent format. + */ +/*================================================================================================*/ void -bwc_set_decomp(bwc_field *const field, uint8 decompX, uint8 decompY, uint8 decompZ, uint8 decompTS) +bwc_set_decomp(bwc_codec *const codec, uint8 decompX, uint8 decompY, uint8 decompZ, uint8 decompTS) { /*-----------------------*\ ! DEFINE FLOAT VARIABLES: ! @@ -2987,14 +2306,14 @@ bwc_set_decomp(bwc_field *const field, uint8 decompX, uint8 decompY, uint8 decom /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); /*--------------------------------------------------------*\ ! Save the global control and info structure to temporary ! ! variables to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; + control = &codec->control; + info = &codec->info; /*--------------------------------------------------------*\ ! Calculate the possible decomposition levels for all ! @@ -3030,14 +2349,13 @@ bwc_set_decomp(bwc_field *const field, 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. ! @@ -3056,7 +2374,7 @@ bwc_set_decomp(bwc_field *const field, uint8 decompX, uint8 decompY, uint8 decom \*--------------------------------------------------------*/ if(initialize_gain_lut()) { - bwc_kill_compression(field); + bwc_free_codec(codec); return; } @@ -3066,7 +2384,7 @@ bwc_set_decomp(bwc_field *const field, uint8 decompX, uint8 decompY, uint8 decom ! tion (10.19) (epsilon = 6, mu = 16) from JPEG2000 by ! ! by David S. Taubman and Michael W. Marcellin (p.437). ! \*--------------------------------------------------------*/ - delta = 1/(pow(2, 2 + PREC_BIT) * sqrt(get_dwt_energy_gain(field, 0, control->nDecomp))); + delta = 1/(pow(2, 2 + PREC_BIT) * sqrt(get_dwt_energy_gain(codec, 0, control->nDecomp))); for(control->qt_exponent = 0; delta < 1; ++control->qt_exponent, delta *= 2); control->qt_mantissa = (uint16)floor(0.5f + ((delta - 1.0f) * (1 << 16))); @@ -3097,41 +2415,19 @@ bwc_set_decomp(bwc_field *const field, uint8 decompX, uint8 decompY, uint8 decom control->CSsgc |= (0x01 << 5); } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void bwc_set_precincts(bwc_field *const field, uint8 pX, uint8 pY, uint8 pZ, uint8 pTS) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function amends the precinct size in the bwc_field structure according to the ! -! specified values. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! px, py, pz, pTS unsigned int(8 bit) - Spatial and temporal precinct dimensions! -! in log2 exponent format. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 15.05.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Amends the precinct size in the bwc_codec structure. + * + * @param[inout] codec Structure defining the compression coder. + * @param[in] pX Precinct size in first dimemsion in log2 exponent format. + * @param[in] pY Precinct size in first dimemsion in log2 exponent format. + * @param[in] pZ Precinct size in third dimemsion in log2 exponent format. + * @param[in] pTS Precinct size in fourth dimemsion in log2 exponent format. + */ +/*================================================================================================*/ void -bwc_set_precincts(bwc_field *const field, uint8 pX, uint8 pY, uint8 pZ, uint8 pTS) +bwc_set_precincts(bwc_codec *const codec, uint8 pX, uint8 pY, uint8 pZ, uint8 pTS) { /*-----------------------*\ ! DEFINE STRUCTS: ! @@ -3142,14 +2438,14 @@ bwc_set_precincts(bwc_field *const field, uint8 pX, uint8 pY, uint8 pZ, uint8 pT /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); /*--------------------------------------------------------*\ ! Save the global control and info structure to temporary ! ! variables to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; + control = &codec->control; + info = &codec->info; /*--------------------------------------------------------*\ ! Check if the precinct sizes are specified for a valid ! @@ -3172,13 +2468,12 @@ bwc_set_precincts(bwc_field *const field, 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. ! @@ -3198,41 +2493,19 @@ bwc_set_precincts(bwc_field *const field, uint8 pX, uint8 pY, uint8 pZ, uint8 pT control->CSsgc |= (0x01 << 6); } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void bwc_set_codeblocks(bwc_field *const field, uint8 cbX, uint8 cbY, ! -! -------------- uint8 cbZ, uint8 cbTS) ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function amends the codeblock size in the bwc_field structure according to the ! -! specified values. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! cbx, cby, cbz, cbTS unsigned int(8 bit) - Spatial and temporal codeblock dimen- ! -! sions in log2 exponent format. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Amends the codeblock size in the bwc_codec structure. + * + * @param[inout] codec Structure defining the compression coder. + * @param[in] cbX Codeblock size in first dimemsion in log2 exponent format. + * @param[in] cbY Codeblock size in first dimemsion in log2 exponent format. + * @param[in] cbZ Codeblock size in third dimemsion in log2 exponent format. + * @param[in] cbTS Codeblock size in fourth dimemsion in log2 exponent format. + */ +/*================================================================================================*/ void -bwc_set_codeblocks(bwc_field *const field, uint8 cbX, uint8 cbY, uint8 cbZ, uint8 cbTS) +bwc_set_codeblocks(bwc_codec *const codec, uint8 cbX, uint8 cbY, uint8 cbZ, uint8 cbTS) { /*-----------------------*\ ! DEFINE STRUCTS: ! @@ -3243,14 +2516,14 @@ bwc_set_codeblocks(bwc_field *const field, uint8 cbX, uint8 cbY, uint8 cbZ, uint /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); /*--------------------------------------------------------*\ ! Save the global control and info structure to temporary ! ! variables to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; + control = &codec->control; + info = &codec->info; /*--------------------------------------------------------*\ ! Check if the codeblock sizes are specified for a valid ! @@ -3271,15 +2544,14 @@ bwc_set_codeblocks(bwc_field *const field, 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. ! @@ -3299,40 +2571,16 @@ bwc_set_codeblocks(bwc_field *const field, uint8 cbX, uint8 cbY, uint8 cbZ, uint control->CSsgc |= (0x01 << 7); } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void bwc_set_qm(bwc_field *const field, uint8 Qm) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function amends the Q number formate range in the bwc_field structure according to the ! -! specified value. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! Qm unsigned int(8 bit) - Q number formate range (m). ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Amends the Q number formate range in the bwc_codec structure. + * + * @param[inout] codec Structure defining the compression coder. + * @param[in] Qm Q number formate range (m). + */ +/*================================================================================================*/ void -bwc_set_qm(bwc_field *const field, uint8 Qm) +bwc_set_qm(bwc_codec *const codec, uint8 Qm) { /*-----------------------*\ ! DEFINE STRUCTS: ! @@ -3342,31 +2590,30 @@ bwc_set_qm(bwc_field *const field, uint8 Qm) /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); /*--------------------------------------------------------*\ ! Save the global control structure to a temporary varia- ! ! ble to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; /*--------------------------------------------------------*\ ! Check if the Q number formate range is valid and amend ! - ! the bwc_field structure accordingly. ! + ! 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 { @@ -3380,54 +2627,25 @@ bwc_set_qm(bwc_field *const field, uint8 Qm) } } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void bwc_set_tiles(bwc_field *const field, uint32 tilesX, uint32 tilesY, uint32 tilesZ, ! -! -------------- uint32 tilesTS, uchar instr) ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function amends the tileSize and num_Tiles values in the bwc_field structure according ! -! to the specified values. The NUMBEROF and SIZEOF constants can be used to either specify ! -! the tile sizes or the number of tiles in each spatial and temporal directions. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! tilesX, tilesY, tilesZ unsigned int(32 bit) - Variables defining the size of ! -! a spatial tile. ! -! ! -! tilesTS unsigned int(32 bit) - Variables defining the size of ! -! a temporal tile. ! -! ! -! instr bwc_tile_instr - Constants used to instruct the ! -! bwc_set_tiles function. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 14.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Amends the tileSize and num_Tiles values in the bwc_codec structure. + * + * @param[inout] codec Structure defining the compression coder. + * @param[in] tilesX Spatial tile size/number in first dimension. + * @param[in] tilesY Spatial tile size/number in second dimension. + * @param[in] tilesZ Spatial tile size/number in third dimension. + * @param[in] tilesTS Spatial tile size/number in fourth dimension. + * @param[in] instr Instructs interpretation of parameters as 'size' or 'number'. + */ +/*================================================================================================*/ void -bwc_set_tiles(bwc_field *const field, uint64 tilesX, uint64 tilesY, uint64 tilesZ, uint16 tilesTS, bwc_tile_instr instr) +bwc_set_tiles(bwc_codec *const codec, uint64 tilesX, uint64 tilesY, uint64 tilesZ, uint64 tilesTS, bwc_tile_instr instr) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ - uint64 num_tiles_X, num_tiles_Y, num_tiles_Z; - uint16 num_tiles_TS; + uint64 num_tiles_X, num_tiles_Y, num_tiles_Z, num_tiles_TS; /*-----------------------*\ ! DEFINE STRUCTS: ! @@ -3438,15 +2656,15 @@ bwc_set_tiles(bwc_field *const field, uint64 tilesX, uint64 tilesY, uint64 tiles /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(instr == bwc_tile_sizeof || instr == bwc_tile_numbof); /*--------------------------------------------------------*\ ! Save the global control and info structure to temporary ! ! variables to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; + control = &codec->control; + info = &codec->info; /*--------------------------------------------------------*\ ! Check if the size of one tile or the overall number of ! @@ -3462,17 +2680,16 @@ bwc_set_tiles(bwc_field *const field, 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; } @@ -3495,7 +2712,7 @@ bwc_set_tiles(bwc_field *const field, uint64 tilesX, uint64 tilesY, uint64 tiles num_tiles_X = (uint64)ceil(((float)info->nX / control->tileSizeX)); num_tiles_Y = (uint64)ceil(((float)info->nY / control->tileSizeY)); num_tiles_Z = (uint64)ceil(((float)info->nZ / control->tileSizeZ)); - num_tiles_TS = (uint16)ceil(((float)info->nTS/ control->tileSizeTS)); + num_tiles_TS = (uint64)ceil(((float)info->nTS/ control->tileSizeTS)); control->nTiles = num_tiles_X * num_tiles_Y * num_tiles_Z * num_tiles_TS; /*--------------------------------------------------------*\ @@ -3504,16 +2721,15 @@ bwc_set_tiles(bwc_field *const field, 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. ! @@ -3534,15 +2750,14 @@ bwc_set_tiles(bwc_field *const field, 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; } @@ -3557,7 +2772,7 @@ bwc_set_tiles(bwc_field *const field, uint64 tilesX, uint64 tilesY, uint64 tiles control->tileSizeX = (info->nX >> 1) ? (tilesX ? (uint64)ceil(((float)info->nX / tilesX)) : info->nX) : info->nX; control->tileSizeY = (info->nY >> 1) ? (tilesY ? (uint64)ceil(((float)info->nY / tilesY)) : info->nY) : info->nY; control->tileSizeZ = (info->nZ >> 1) ? (tilesZ ? (uint64)ceil(((float)info->nZ / tilesZ)) : info->nZ) : info->nZ; - control->tileSizeTS = (info->nTS >> 1) ? (tilesTS ? (uint16)ceil(((float)info->nTS/ tilesTS)) : info->nTS) : info->nTS; + control->tileSizeTS = (info->nTS >> 1) ? (tilesTS ? (uint64)ceil(((float)info->nTS/ tilesTS)) : info->nTS) : info->nTS; /*--------------------------------------------------------*\ ! Check if the tile sizes have valid values. ! @@ -3567,18 +2782,17 @@ bwc_set_tiles(bwc_field *const field, 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. ! @@ -3597,7 +2811,7 @@ bwc_set_tiles(bwc_field *const field, uint64 tilesX, uint64 tilesY, uint64 tiles num_tiles_X = (uint64)ceil(((float)info->nX / control->tileSizeX)); num_tiles_Y = (uint64)ceil(((float)info->nY / control->tileSizeY)); num_tiles_Z = (uint64)ceil(((float)info->nZ / control->tileSizeZ)); - num_tiles_TS = (uint16)ceil(((float)info->nTS/ control->tileSizeTS)); + num_tiles_TS = (uint64)ceil(((float)info->nTS/ control->tileSizeTS)); control->nTiles = num_tiles_X * num_tiles_Y * num_tiles_Z * num_tiles_TS; } @@ -3608,45 +2822,111 @@ bwc_set_tiles(bwc_field *const field, uint64 tilesX, uint64 tilesY, uint64 tiles control->CSsgc |= (0x01 << 9); } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void bwc_create_compression(bwc_field *field, char *rate_control) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function creates the field structure used to compress a floating point array defined ! -! by the bwc_initialize function. For a compression run, the rate_control and instr arguments ! -! need to be passed to the function to properly set up the lossy compression stage. Here, the ! -! instr parameter defines whether rate control is defined by a BITRATE - a floating point val-! -! ue defining the average number of bits per datapoint - and ACCURACY - an integer value de- ! -! fining the exponent of the maximum allowable error (i.e. 15 for err = 1e-15). ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! rate_control char* - Variable defining the bitrate. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! 05.12.2019 Patrick vogler B87E7E4 V 0.1.0 streamlined function arguments ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details 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 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); + } +} + +/*================================================================================================*/ +/** + * @details Creates the codec structure used to compress floating point data in a previously + * initialized instance of the bwc_stream structure. + * + * @param[inout] codec Pointer to the returned codec structure. + * @param[in] stream Stream data structure containing the relevant floating point data. + * @param[in] rate_control The bitrates of several quality layers as string variable. + * + * @retval uchar + */ +/*================================================================================================*/ uchar -bwc_create_compression(bwc_field *field, char *rate_control) +bwc_create_compression(bwc_codec *codec, bwc_stream *stream, char *rate_control) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -3673,14 +2953,15 @@ bwc_create_compression(bwc_field *field, char *rate_control) /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); + assert(stream); /*--------------------------------------------------------*\ ! Save the global control structure to a temporary varia- ! ! ble to make the code more readable. ! \*--------------------------------------------------------*/ - info = field->info; - control = &field->control; + info = &codec->info; + control = &codec->control; /*--------------------------------------------------------*\ ! Allocate the array used to hold the quality layer bit- ! @@ -3767,10 +3048,10 @@ bwc_create_compression(bwc_field *field, char *rate_control) control->bitrate = realloc(control->bitrate, control->nLayers * sizeof(float)); /*--------------------------------------------------------*\ - ! Create the field structure used to compress a floating ! + ! Create the codec structure used to compress a floating ! ! point array defined by the bwc_initialize function. ! \*--------------------------------------------------------*/ - if(create_field(field)) + if(create_codec(codec)) { return 1; } @@ -3778,17 +3059,17 @@ bwc_create_compression(bwc_field *field, char *rate_control) /*--------------------------------------------------------*\ ! Evaluate the size of the main header. ! \*--------------------------------------------------------*/ - /*control->headerSize = 108 + info->nPar * (25 + control->nTiles * 2 * PREC_BYTE) - + control->nLayers * 4; + control->headerSize = 111 + info->nPar * control->nTiles * 2 * PREC_BYTE + + control->nLayers * 4; - if(field->aux != NULL) + if(stream->codestream.aux != NULL) { - control->headerSize += 6 + field->aux->size; + control->headerSize += 6 + stream->codestream.aux->size; } - if(field->com != NULL) + if(stream->codestream.com != NULL) { - control->headerSize += 6 + field->com->size; + control->headerSize += 6 + stream->codestream.com->size; } if(control->headerSize >= 0xFFFFFFFF) @@ -3803,46 +3084,29 @@ bwc_create_compression(bwc_field *field, char *rate_control) "o==========================================================o\n"); return 1; - }*/ + } return 0; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar bwc_compress(bwc_field *const field, bwc_float *const data) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! Description needed. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! uchar - Returns an unsigned char for error handling. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ -uchar -bwc_compress(bwc_field *const field, bwc_data *const data) +/*================================================================================================*/ +/** + * @details Compress the data of a readily initialized bwc_stream structure using the coder + * defined by the codec variable. + * + * @param[inout] codec Pointer to the returned codec structure. + * @param[in] stream Stream data structure containing the relevant floating point data. + * + * @retval size_t + */ +/*================================================================================================*/ +size_t +bwc_compress(bwc_codec *const codec, bwc_stream *const stream) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ + size_t compressed_size = 0; uint64 buff_size = 0; uint64 i; uint16 p; @@ -3883,8 +3147,8 @@ bwc_compress(bwc_field *const field, bwc_data *const data) /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); - assert(data); + assert(codec); + assert(stream); /*--------------------------------------------------------*\ ! Initialize the compression time measurement. ! @@ -3901,40 +3165,8 @@ bwc_compress(bwc_field *const field, bwc_data *const data) ! Save the global control and info structure to temporary ! ! variables to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; - - /*--------------------------------------------------------*\ - ! Evaluate the size of the main header. ! - \*--------------------------------------------------------*/ - control->headerSize = 108 + info->nPar * (25 + control->nTiles * 2 * PREC_BYTE) - + control->nLayers * 4; - - if(data->codestream.aux != NULL) - { - field->aux = data->codestream.aux; - control->headerSize += 6 + field->aux->size; - } - - if(data->codestream.com != NULL) - { - field->com = data->codestream.com; - control->headerSize += 6 + field->com->size; - } - - if(control->headerSize >= 0xFFFFFFFF) - { - fprintf(stderr,"o==========================================================o\n"\ - "| ERROR: Main header exceeds maximum size limit |\n"\ - "| |\n"\ - "| Appending the auxiliary information to the main |\n"\ - "| header would exceed its maximum size limit of |\n"\ - "| 4294967295 bytes. |\n"\ - "| |\n"\ - "o==========================================================o\n"); - - return 1; - } + control = &codec->control; + info = &codec->info; /*--------------------------------------------------------*\ ! Evaluate the working buffer size and allocate it accord- ! @@ -3948,7 +3180,7 @@ bwc_compress(bwc_field *const field, bwc_data *const data) { // memory allocation error fprintf(stderr, MEMERROR); - return 1; + return 0; } /*--------------------------------------------------------*\ @@ -3961,7 +3193,7 @@ bwc_compress(bwc_field *const field, bwc_data *const data) ! Save the tile structure in a temporary variable to make ! ! the code more readable. ! \*--------------------------------------------------------*/ - tile = &field->tile[i]; + tile = &codec->tile[i]; for(p = 0; p < info->nPar; ++p) { @@ -3982,7 +3214,7 @@ bwc_compress(bwc_field *const field, bwc_data *const data) start = (double)clock(); #endif #endif - fill_buffer(field, tile, parameter, working_buffer, data, p); + fill_buffer(codec, tile, parameter, working_buffer, stream, p); #ifdef BWC_PROFILE #if defined (_OPENMP) end = omp_get_wtime(); @@ -4005,7 +3237,7 @@ bwc_compress(bwc_field *const field, bwc_data *const data) start = (double)clock(); #endif #endif - normalize_param(field, parameter); + normalize_param(codec, parameter); #ifdef BWC_PROFILE #if defined (_OPENMP) end = omp_get_wtime(); @@ -4026,10 +3258,10 @@ bwc_compress(bwc_field *const field, bwc_data *const data) start = (double)clock(); #endif #endif - if(forward_wavelet_transform(field, parameter)) + if(forward_wavelet_transform(codec, parameter)) { free(working_buffer); - return 1; + return 0; } #ifdef BWC_PROFILE #if defined (_OPENMP) @@ -4051,10 +3283,10 @@ bwc_compress(bwc_field *const field, bwc_data *const data) start = (double)clock(); #endif #endif - if(t1_encode(field, tile, parameter)) + if(t1_encode(codec, tile, parameter)) { free(working_buffer); - return 1; + return 0; } #ifdef BWC_PROFILE #if defined (_OPENMP) @@ -4082,10 +3314,10 @@ bwc_compress(bwc_field *const field, bwc_data *const data) start = (double)clock(); #endif #endif - if(t2_encode(field, tile)) + if(t2_encode(codec, tile)) { free(working_buffer); - return 1; + return 0; } #ifdef BWC_PROFILE #if defined (_OPENMP) @@ -4107,11 +3339,11 @@ bwc_compress(bwc_field *const field, bwc_data *const data) start = (double)clock(); #endif #endif - data->codestream.data = assemble_codestream(field); - if(!data->codestream.data) + compressed_size = assemble_codestream(codec, stream); + if(compressed_size == 0) { free(working_buffer); - return 1; + return 0; } #ifdef BWC_PROFILE #if defined (_OPENMP) @@ -4138,8 +3370,8 @@ bwc_compress(bwc_field *const field, bwc_data *const data) ttl = ((double)clock() - ttl)/CLOCKS_PER_SEC; #endif - nfs = (uint64)(info->nX * info->nY * info->nZ * info->nTS * info->nPar * info->precision); - css = (uint64)data->codestream.data->size; + nfs = (uint64)(info->nX * info->nY * info->nZ * info->nTS * info->nPar * info->data_prec); + css = (uint64)compressed_size; cpr = (double)nfs/css; @@ -4161,119 +3393,60 @@ bwc_compress(bwc_field *const field, bwc_data *const data) /*--------------------------------------------------------*\ ! Return to the function caller. ! \*--------------------------------------------------------*/ - return 0; + return compressed_size; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar bwc_create_compression(bwc_field *field_ptr, char *rate_control, uchar instr) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function parses the supplied bwc codestream and sets up the field structure used to ! -! decompress the numerical dataset. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! rate_control (opt) char* - Variable defining the bitrate/accuracy. ! -! ! -! instr (opt) bwc_rate_instr - Constants used to instruct the rate ! -! control information. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ -bwc_field * -bwc_create_decompression(bwc_data *const data, uint8 layer) +/*================================================================================================*/ +/** + * @details Creates the codec structure used to decompress floating point data in a previously + * initialized instance of the bwc_stream structure. + * + * @param[inout] codec Pointer to the returned codec structure. + * @param[in] stream Stream data structure containing the relevant floating point data. + * @param[in] layer Number of quality layers. + * + * @retval uchar + */ +/*================================================================================================*/ +uchar +bwc_create_decompression(bwc_codec *const codec, bwc_stream *const stream, uint8 layer) { - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_field *field; - /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(data); + assert(codec); + assert(stream); /*--------------------------------------------------------*\ - ! Parse the codestream and setup the field codestream. ! + ! Parse the stream and setup the codec. ! \*--------------------------------------------------------*/ - field = parse_codestream(data, layer); - if(!field) + parse_codestream(codec, stream, layer); + if(!codec) { - return NULL; + return 1; } - /*--------------------------------------------------------*\ - ! If successful, return the field structure to the func- ! - ! tion caller. ! - \*--------------------------------------------------------*/ - return field; + return 0; } -/*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar bwc_create_compression(bwc_field *field, float rate_control, uchar instr) ! -! -------------- ! -! ! -! DESCRIPTION: ! -! ------------ ! -! This function creates the field structure used to compress a floating point array defined ! -! by the bwc_initialize function at a prescribed bitrate or accuracy. In this context, the ! -! bitrate is a floating point value defining the average number of bits per datapoint and ! -! the accuracy is an integer value defining the exponent of the maximum allowable error ! -! (i.e. 15 for err = 1e-15). ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! -! rate_control float - Variable defining the bitrate/accuracy. ! -! ! -! instr unsigned char - Constants used to instruct the rate ! -! control information. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description Of Change ! -! ---- ------ --------- ------- --------------------- ! -! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ +/*================================================================================================*/ +/** + * @details Decompress the data of a readily initialized bwc_stream structure using the coder + * defined by the codec variable. + * + * @param[inout] codec Pointer to the returned codec structure. + * @param[in] stream Stream data structure containing the relevant floating point data. + * + * @retval uchar + */ +/*================================================================================================*/ uchar -bwc_decompress(bwc_field *const field, bwc_data *const data) +bwc_decompress(bwc_codec *const codec, bwc_stream *const stream) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ uint64 buff_size; - uint64 single_size, double_size; uint64 i; uint16 p; @@ -4300,13 +3473,12 @@ bwc_decompress(bwc_field *const field, bwc_data *const data) bwc_tile *tile; bwc_parameter *parameter; bwc_sample *working_buffer; - bwc_cmd_opts_ll *param; /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); - assert(data); + assert(codec); + assert(stream); /*--------------------------------------------------------*\ ! Initialize the decompression time measurement. ! @@ -4323,42 +3495,8 @@ bwc_decompress(bwc_field *const field, bwc_data *const data) ! Save the global control and info structure to temporary ! ! variables to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; - - /*--------------------------------------------------------*\ - ! Calculate the field size after subsampling and allocate ! - ! the field memory blocks. ! - \*--------------------------------------------------------*/ - if(data->info.parameter) - { - param = data->info.parameter->root; - double_size = - single_size = 0; - - while(param != NULL) - { - if(param->precision == 8) - { - double_size += param->size; - } - else if (param->precision == 4) - { - single_size += param->size; - } - - param = param -> next; - } - } - - data->field.d = calloc(double_size, sizeof(double)); - data->field.f = calloc(single_size, sizeof(float)); - if(!data->field.d || !data->field.f) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return 1; - } + control = &codec->control; + info = &codec->info; /*--------------------------------------------------------*\ ! Evaluate the working buffer size and allocate it accord- ! @@ -4385,7 +3523,7 @@ bwc_decompress(bwc_field *const field, bwc_data *const data) ! Save the tile structure in a temporary variable to make ! ! the code more readable. ! \*--------------------------------------------------------*/ - tile = &field->tile[i]; + tile = &codec->tile[i]; for(p = 0; p < info->nPar; ++p) { @@ -4411,7 +3549,7 @@ bwc_decompress(bwc_field *const field, bwc_data *const data) start = (double)clock(); #endif #endif - if(t1_decode(field, tile, parameter)) + if(t1_decode(codec, tile, parameter)) { free(working_buffer); return 1; @@ -4436,7 +3574,7 @@ bwc_decompress(bwc_field *const field, bwc_data *const data) start = (double)clock(); #endif #endif - if(inverse_wavelet_transform(field, parameter)) + if(inverse_wavelet_transform(codec, parameter)) { free(working_buffer); return 1; @@ -4462,7 +3600,7 @@ bwc_decompress(bwc_field *const field, bwc_data *const data) start = (double)clock(); #endif #endif - denormalize_param(field, parameter); + denormalize_param(codec, parameter); #ifdef BWC_PROFILE #if defined (_OPENMP) end = omp_get_wtime(); @@ -4485,7 +3623,7 @@ bwc_decompress(bwc_field *const field, bwc_data *const data) start = (double)clock(); #endif #endif - flush_buffer(field, tile, parameter, working_buffer, data, p); + flush_buffer(codec, tile, parameter, working_buffer, stream, p); #ifdef BWC_PROFILE #if defined (_OPENMP) end = omp_get_wtime(); @@ -4528,4 +3666,4 @@ bwc_decompress(bwc_field *const field, bwc_data *const data) return 0; -} \ No newline at end of file +} diff --git a/src/library/tier1.c b/src/library/tier1.c index 60abda2..1bc59fc 100755 --- a/src/library/tier1.c +++ b/src/library/tier1.c @@ -16,7 +16,7 @@ || ------------ || || || || This file describes a set of functions that can be used to de-/encode bwc || -|| codeblocks described by the bwc_field structure according to the embedded block || +|| codeblocks described by the bwc_codec structure according to the embedded block || || coding paradigm described by the JPEG 2000 standard. For more information please || || refere to JPEG2000 by D. S. Taubman and M. W. Marcellin. || || || @@ -398,9 +398,8 @@ cblkreset_inv(bwc_coder_stripe *const cblk, const uint64 width, const uint64 hei uint64 i; uint64 limit; uint64 cblk_stripe; - uint64 x, y, z; + uint64 x, y, z, t; int64 idx_u, idx_r, idx_d, idx_l; - uint16 t; uint8 s; /*-----------------------*\ @@ -533,15 +532,12 @@ cblkcopy_forward(bwc_coder_stripe *const destination, bwc_sample *const source, \*-----------------------*/ bwc_raw buff, sign_mask; uint64 bit_mask, limit; - uint64 cblk_width, cblk_height, cblk_depth, cblk_stripe; + uint64 cblk_width, cblk_height, cblk_depth, cblk_dt, cblk_stripe; uint64 incrX, incrY, incrZ; - uint64 i, x, y, z; - uint64 X0, Y0, Z0; - uint64 X1, Y1, Z1; + uint64 i, x, y, z, t; + uint64 X0, Y0, Z0, TS0; + uint64 X1, Y1, Z1, TS1; int64 idx_u, idx_r, idx_d, idx_l; - uint16 TS0, TS1; - uint16 cblk_dt; - uint16 t; uint8 b, Kmax, s; /*-----------------------*\ @@ -775,15 +771,12 @@ cblkcopy_inverse(bwc_coder_stripe *const source, bwc_sample *const destinat /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ - uint64 cblk_width, cblk_height, cblk_depth, cblk_stripe; + uint64 cblk_width, cblk_height, cblk_depth, cblk_dt, cblk_stripe; uint64 bit_shift, buff, limit; uint64 incrX, incrY, incrZ; - uint64 i, x, y, z; - uint64 X0, Y0, Z0; - uint64 X1, Y1, Z1; - uint16 TS0, TS1; - uint16 cblk_dt; - uint16 t; + uint64 i, x, y, z, t; + uint64 X0, Y0, Z0, TS0; + uint64 X1, Y1, Z1, TS1; uint8 bitplane; uint8 codingpass; uint8 s; @@ -2274,12 +2267,12 @@ compute_convex_hull(bwc_encoded_cblk *const encoded_codeblock, double *const mse } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: bwc_encoded_cblk* encode_codeblock(bwc_field *const field, bwc_cblk_access *const access, ! +! FUNCTION NAME: void encode_codeblock(bwc_codec *const codec, bwc_cblk_access *const access, ! ! -------------- bwc_coder_stripe *const codeblock, ! ! const uint64 width, ! ! const uint64 height, ! ! const uint64 depth, ! -! const uint16 dt) ! +! const uint64 dt) ! ! ! ! ! ! DESCRIPTION: ! @@ -2307,12 +2300,12 @@ compute_convex_hull(bwc_encoded_cblk *const encoded_codeblock, double *const mse ! ! \*----------------------------------------------------------------------------------------------------------*/ static void -encode_codeblock(bwc_field *const field, bwc_cblk_access *const access, +encode_codeblock(bwc_codec *const codec, bwc_cblk_access *const access, bwc_coder_stripe *const codeblock, const uint64 width, const uint64 height, const uint64 depth, - const uint16 dt) + const uint64 dt) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -2340,7 +2333,7 @@ encode_codeblock(bwc_field *const field, bwc_cblk_access *const access, /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(access); assert(codeblock); assert(access->subband->control.highband_flag <= 15); @@ -2359,7 +2352,7 @@ encode_codeblock(bwc_field *const field, bwc_cblk_access *const access, ! info and encoded block structure to temporary variables ! ! to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; subb_ctrl = &access->subband->control; subb_inf = &access->subband->info; @@ -2595,12 +2588,12 @@ encode_codeblock(bwc_field *const field, bwc_cblk_access *const access, } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: bwc_encoded_cblk* encode_codeblock(bwc_field *const field, bwc_cblk_access *const access, ! +! FUNCTION NAME: void decode_codeblock(bwc_codec *const codec, bwc_cblk_access *const access, ! ! bwc_coder_stripe *const codeblock, ! ! const uint64 width, ! ! const uint64 height, ! ! const uint64 depth, ! -! const uint16 dt) ! +! const uint64 dt) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -2628,12 +2621,12 @@ encode_codeblock(bwc_field *const field, bwc_cblk_access *const access, ! ! \*----------------------------------------------------------------------------------------------------------*/ static void -decode_codeblock(bwc_field *const field, bwc_cblk_access *const access, +decode_codeblock(bwc_codec *const codec, bwc_cblk_access *const access, bwc_coder_stripe *const codeblock, const uint64 width, const uint64 height, const uint64 depth, - const uint16 dt) + const uint64 dt) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -2652,7 +2645,7 @@ decode_codeblock(bwc_field *const field, bwc_cblk_access *const access, /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(access); assert(codeblock); assert(access->subband->control.highband_flag <= 15); @@ -2671,7 +2664,7 @@ decode_codeblock(bwc_field *const field, bwc_cblk_access *const access, ! structure to temporary variables to make the code more ! ! readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; subb_ctrl = &access->subband->control; @@ -2828,20 +2821,19 @@ decode_codeblock(bwc_field *const field, bwc_cblk_access *const access, ! ! \*----------------------------------------------------------------------------------------------------------*/ uchar -t1_encode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const parameter) +t1_encode(bwc_codec *const codec, bwc_tile *const tile, bwc_parameter *const parameter) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ uint64 c; - uint64 cbSizeX, cbSizeY, cbSizeZ; + uint64 cbSizeX, cbSizeY, cbSizeZ, cbSizeTS; uint64 width, height, depth; int64 buff_size; int64 i, j; int64 nThreads; - uint16 cbSizeTS; uint16 slope_max, slope_min; int16 z; @@ -2857,7 +2849,7 @@ t1_encode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const par /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(tile); assert(parameter); @@ -2865,7 +2857,7 @@ t1_encode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const par ! Save the global control structure to a temporary varia- ! ! ble to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; /*--------------------------------------------------------*\ ! Save the minimum and maximum slope values for the cur- ! @@ -3040,7 +3032,7 @@ t1_encode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const par ! truncation points (L) and possible slope values (S) in ! ! the bwc_encoded_cblk structure. ! \*--------------------------------------------------------*/ - encode_codeblock(field, ¶meter->access[c], working_buffer, + encode_codeblock(codec, ¶meter->access[c], working_buffer, cbSizeX, cbSizeY, cbSizeZ, cbSizeTS); @@ -3131,21 +3123,19 @@ t1_encode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const par ! ! \*----------------------------------------------------------------------------------------------------------*/ uchar -t1_decode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const parameter) +t1_decode(bwc_codec *const codec, bwc_tile *const tile, bwc_parameter *const parameter) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ uint64 c; - uint64 cbSizeX, cbSizeY, cbSizeZ; + uint64 cbSizeX, cbSizeY, cbSizeZ, cbSizeTS; uint64 width, height, depth; int64 buff_size; int64 i, j; int64 nThreads; - uint16 cbSizeTS; - /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ @@ -3159,7 +3149,7 @@ t1_decode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const par /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(tile); assert(parameter); @@ -3167,7 +3157,7 @@ t1_decode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const par ! Save the global control structure to a temporary varia- ! ! ble to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; + control = &codec->control; /*--------------------------------------------------------*\ ! Evaluate the width, height and depth of the current ! @@ -3332,7 +3322,7 @@ t1_decode(bwc_field *const field, bwc_tile *const tile, bwc_parameter *const par if(codeblock->encoded_block->Z > 0) { - decode_codeblock(field, ¶meter->access[c], working_buffer, + decode_codeblock(codec, ¶meter->access[c], working_buffer, cbSizeX, cbSizeY, cbSizeZ, cbSizeTS); } diff --git a/src/library/tier2.c b/src/library/tier2.c index 96ac025..7aa0c9d 100755 --- a/src/library/tier2.c +++ b/src/library/tier2.c @@ -16,7 +16,7 @@ || ------------ || || || || This file describes a set of functions that can be used to de-/encode bwc || -|| codeblocks described by the bwc_field structure according to the embedded block || +|| codeblocks described by the bwc_codec structure according to the embedded block || || coding paradigm described by the JPEG 2000 standard. For more information please || || refere to JPEG2000 by D. S. Taubman and M. W. Marcellin. || || || @@ -312,7 +312,7 @@ encode_length(bitstream *const header, bwc_codeblock *const codeblock, } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void create_quality_layers(bwc_field *const field, bwc_tile *const tile) ! +! FUNCTION NAME: ! ! -------------- ! ! ! ! ! @@ -385,11 +385,10 @@ decode_length(bitstream *const header, bwc_codeblock *const codeblock, int8 cons } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: int64 create_packet(bwc_field *const field, bwc_tile *const tile, ! -! -------------- bwc_resolution *const resolution, ! -! uint32 const prec_idx, ! -! int8 const q_layer, ! -! uchar const est) ! +! FUNCTION NAME: int64 create_packet(bwc_tile *const tile, bwc_resolution *const resolution, ! +! -------------- uint32 const prec_idx, ! +! int8 const q_layer, ! +! uchar const est) ! ! ! ! DESCRIPTION: ! ! ------------ ! @@ -403,9 +402,6 @@ decode_length(bitstream *const header, bwc_codeblock *const codeblock, int8 cons ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! -! decompression stage. ! -! ! ! tile bwc_tile* - Structure defining a bwc tile. ! ! ! ! resolution bwc_resolution* - Structure defining a bwc resolution ! @@ -435,11 +431,10 @@ decode_length(bitstream *const header, bwc_codeblock *const codeblock, int8 cons ! ! \*----------------------------------------------------------------------------------------------------------*/ static int32 -create_packet(bwc_field *const field, bwc_tile *const tile, - bwc_resolution *const resolution, - uint32 const prec_idx, - int16 const q_layer, - uchar const est) +create_packet(bwc_tile *const tile, bwc_resolution *const resolution, + uint32 const prec_idx, + int16 const q_layer, + uchar const est) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -450,6 +445,7 @@ create_packet(bwc_field *const field, bwc_tile *const tile, int16 *cp_contr; int16 delta_z; int8 m; + uchar *memory; /*-----------------------*\ ! DEFINE STRUCTS: ! @@ -462,7 +458,6 @@ create_packet(bwc_field *const field, bwc_tile *const tile, /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); assert(tile); assert(resolution); @@ -482,7 +477,14 @@ create_packet(bwc_field *const field, bwc_tile *const tile, ! Initialize the stream that is used to assemble the pack- ! ! et header. ! \*--------------------------------------------------------*/ - header = init_stream(NULL, PACKET_HEADER_SIZE, 'c'); + memory = calloc(PACKET_HEADER_SIZE, sizeof(uchar)); + if(!memory) + { + // memory allocation error + fprintf(stderr, MEMERROR); + return -1; + } + header = init_bitstream(memory, PACKET_HEADER_SIZE, 'c'); if(!header) { // memory allocation error @@ -498,7 +500,7 @@ create_packet(bwc_field *const field, bwc_tile *const tile, if(!est) { packet->body.access = - packet->body.memory = calloc(packet->body.size, sizeof(bwc_stream)); + packet->body.memory = calloc(packet->body.size, sizeof(bwc_span)); if(!packet->body.memory) { // memory allocation error @@ -644,7 +646,8 @@ create_packet(bwc_field *const field, bwc_tile *const tile, } k = header->L; - terminate_stream(header, NULL); + free(header->memory); + free(header); return k; } /*--------------------------------------------------------*\ @@ -655,11 +658,13 @@ create_packet(bwc_field *const field, bwc_tile *const tile, \*--------------------------------------------------------*/ else { - if(terminate_stream(header, &packet->header)) + if(shrink_to_fit(header)) { // memory allocation error return -1; } + transfer_to_span(header, &packet->header); + free(header); packet->size = packet->body.size + packet->header.size; @@ -706,7 +711,7 @@ create_packet(bwc_field *const field, bwc_tile *const tile, } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar create_packets(bwc_field *const field, bwc_tile *const tile) ! +! FUNCTION NAME: uchar create_packets(bwc_codec *const codec, bwc_tile *const tile) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -723,7 +728,7 @@ create_packet(bwc_field *const field, bwc_tile *const tile, ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! +! codec bwc_codec* - Structure defining the compression/ ! ! decompression stage. ! ! ! ! tile bwc_tile* - Structure defining a bwc tile. ! @@ -743,7 +748,7 @@ create_packet(bwc_field *const field, bwc_tile *const tile, ! ! \*----------------------------------------------------------------------------------------------------------*/ static uchar -create_packets(bwc_field *const field, bwc_tile *const tile) +create_packets(bwc_codec *const codec, bwc_tile *const tile) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -764,15 +769,15 @@ create_packets(bwc_field *const field, bwc_tile *const tile) /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(tile); /*--------------------------------------------------------*\ ! Save the global control and info structure to temporary ! ! variables to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; + control = &codec->control; + info = &codec->info; /*--------------------------------------------------------*\ ! Iterate overall quality layers for every precinct in all ! @@ -799,7 +804,7 @@ create_packets(bwc_field *const field, bwc_tile *const tile) { for(l = 0; l < control->nLayers; ++l) { - if(create_packet(field, tile, resolution, p, l, 0) < 0) + if(create_packet(tile, resolution, p, l, 0) < 0) { // memory allocation error return 1; @@ -845,7 +850,7 @@ create_packets(bwc_field *const field, bwc_tile *const tile) /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: int64 create_quality_layer(bwc_field *const field, bwc_tile *const tile, ! +! FUNCTION NAME: int64 create_quality_layer(bwc_codec *const codec, bwc_tile *const tile, ! ! -------------- uint16 const threshold, ! ! int16 const q_layer, ! ! uchar const est) ! @@ -860,7 +865,7 @@ create_packets(bwc_field *const field, bwc_tile *const tile) ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! +! codec bwc_codec* - Structure defining the compression/ ! ! decompression stage. ! ! ! ! tile bwc_tile* - Structure defining a bwc tile. ! @@ -888,7 +893,7 @@ create_packets(bwc_field *const field, bwc_tile *const tile) ! ! \*----------------------------------------------------------------------------------------------------------*/ static int64 -create_quality_layer(bwc_field *const field, bwc_tile *const tile, +create_quality_layer(bwc_codec *const codec, bwc_tile *const tile, uint16 const threshold, int16 const q_layer, uchar const est) @@ -916,15 +921,15 @@ create_quality_layer(bwc_field *const field, bwc_tile *const tile, /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(tile); /*--------------------------------------------------------*\ ! Save the global control and info structure to temporary ! ! variables to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; + control = &codec->control; + info = &codec->info; for(j = 0, estimated_ql_size = 0; j < info->nPar; ++j) { @@ -1056,7 +1061,7 @@ create_quality_layer(bwc_field *const field, bwc_tile *const tile, for(p = 0; p < resolution->control.number_of_precincts; ++p) { - estimated_ph_size = create_packet(field, tile, resolution, p, q_layer, est + 1); + estimated_ph_size = create_packet(tile, resolution, p, q_layer, est + 1); if(estimated_ph_size < 0) { @@ -1075,7 +1080,7 @@ create_quality_layer(bwc_field *const field, bwc_tile *const tile, /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: void create_quality_layers(bwc_field *const field, bwc_tile *const tile) ! +! FUNCTION NAME: void create_quality_layers(bwc_codec *const codec, bwc_tile *const tile) ! ! -------------- ! ! ! ! ! @@ -1087,7 +1092,7 @@ create_quality_layer(bwc_field *const field, bwc_tile *const tile, ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! +! codec bwc_codec* - Structure defining the compression/ ! ! decompression stage. ! ! ! ! tile bwc_tile* - Structure defining a bwc tile. ! @@ -1107,7 +1112,7 @@ create_quality_layer(bwc_field *const field, bwc_tile *const tile, ! ! \*----------------------------------------------------------------------------------------------------------*/ static uchar -create_quality_layers(bwc_field *const field, bwc_tile *const tile) +create_quality_layers(bwc_codec *const codec, bwc_tile *const tile) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -1131,15 +1136,15 @@ create_quality_layers(bwc_field *const field, bwc_tile *const tile) /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(tile); /*--------------------------------------------------------*\ ! Save the global and tile control and info structure to ! ! temporary variables to make the code more readable. ! \*--------------------------------------------------------*/ - control = &field->control; - info = field->info; + control = &codec->control; + info = &codec->info; tile_control = &tile->control; tile_info = &tile->info; @@ -1189,7 +1194,7 @@ create_quality_layers(bwc_field *const field, bwc_tile *const tile) { slope = (slope_max + slope_min) >> 1; - estimated_ql_size = create_quality_layer(field, tile, slope, l, 1); + estimated_ql_size = create_quality_layer(codec, tile, slope, l, 1); if(estimated_ql_size >= 0) { @@ -1234,7 +1239,7 @@ create_quality_layers(bwc_field *const field, bwc_tile *const tile) slope = 0; } - estimated_ql_size = create_quality_layer(field, tile, slope, l, 0); + estimated_ql_size = create_quality_layer(codec, tile, slope, l, 0); if(estimated_ql_size >= 0) { @@ -1255,7 +1260,7 @@ create_quality_layers(bwc_field *const field, bwc_tile *const tile) || || \************************************************************************************************************/ /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar t2_encode(bwc_field *const field, bwc_tile *const tile) ! +! FUNCTION NAME: uchar t2_encode(bwc_codec *const codec, bwc_tile *const tile) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -1269,7 +1274,7 @@ create_quality_layers(bwc_field *const field, bwc_tile *const tile) ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! +! codec bwc_codec* - Structure defining the compression/ ! ! decompression stage. ! ! ! ! tile bwc_tile* - Structure defining a bwc tile. ! @@ -1289,19 +1294,19 @@ create_quality_layers(bwc_field *const field, bwc_tile *const tile) ! ! \*----------------------------------------------------------------------------------------------------------*/ uchar -t2_encode(bwc_field *const field, bwc_tile *const tile) +t2_encode(bwc_codec *const codec, bwc_tile *const tile) { /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(tile); /*--------------------------------------------------------*\ ! Create the quality layers according to the bitrate val- ! ! ues provided by the user. ! \*--------------------------------------------------------*/ - if(create_quality_layers(field, tile)) + if(create_quality_layers(codec, tile)) { return 1; } @@ -1310,7 +1315,7 @@ t2_encode(bwc_field *const field, bwc_tile *const tile) ! Create the data packets according to the quality layers ! ! evaluated in the previous step. ! \*--------------------------------------------------------*/ - if(create_packets(field, tile)) + if(create_packets(codec, tile)) { return 1; } @@ -1319,7 +1324,7 @@ t2_encode(bwc_field *const field, bwc_tile *const tile) } /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: uchar parse_packet(bwc_field *const field, bwc_tile *const tile, ! +! FUNCTION NAME: uchar parse_packet(bwc_codec *const codec, bwc_tile *const tile, ! ! -------------- bwc_packet *const packet, ! ! uint64 const body_size) ! ! ! @@ -1332,7 +1337,7 @@ t2_encode(bwc_field *const field, bwc_tile *const tile) ! ----------- ! ! Variable Type Description ! ! -------- ---- ----------- ! -! field bwc_field* - Structure defining the compression/ ! +! codec bwc_codec* - Structure defining the compression/ ! ! decompression stage. ! ! ! ! tile bwc_tile* - Structure defining a bwc tile. ! @@ -1356,7 +1361,7 @@ t2_encode(bwc_field *const field, bwc_tile *const tile) ! ! \*----------------------------------------------------------------------------------------------------------*/ uchar -parse_packet(bwc_field *const field, bwc_tile *const tile, +parse_packet(bwc_codec *const codec, bwc_tile *const tile, bwc_packet *const packet, uint64 const body_size) { @@ -1382,7 +1387,7 @@ parse_packet(bwc_field *const field, bwc_tile *const tile, /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(field); + assert(codec); assert(tile); assert(packet); @@ -1392,7 +1397,7 @@ parse_packet(bwc_field *const field, bwc_tile *const tile, ! Initialize the stream that is used to parse the packet ! ! codestream. ! \*--------------------------------------------------------*/ - header = init_stream(packet->header.memory, body_size, 'd'); + header = init_bitstream(packet->header.memory, body_size, 'd'); if(!header) { // memory allocation error @@ -1572,7 +1577,7 @@ parse_packet(bwc_field *const field, bwc_tile *const tile, ! If the error resilience mode is active for the current ! ! codestream... ! \*--------------------------------------------------------*/ - if(field->control.error_resilience) + if(codec->control.error_resilience) { /*--------------------------------------------------------*\ ! check if the next symbol corresponds to the end of pack- ! diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index 0749c24..b6a8d2b 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -1,2489 +1,1189 @@ -/*====================================================================================================================*\ -|| || -|| /$$$$$$$ /$$ /$$ /$$ /$$ || -|| | $$__ $$|__/ | $$ /$ | $$| $$ || -|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || -|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || -|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || -|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || -|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || -|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || -|| /$$ \ $$ | $$ || -|| | $$$$$$/ | $$ || -|| \______/ |__/ || -|| || -|| DESCRIPTION: || -|| ------------ || -|| This is a simple command line tool that uses the Big Whoop library to (de)com- || -|| press a 2- to 4-dimensional IEEE 754 floating point array. For further infor- || -|| mation use the --help (-h) argument in the command-line or consult the appro- || -|| priate README file. || -|| || -|| FILE REFERENCES: || -|| ---------------- || -|| || -|| Name I/O Description || -|| ---- --- ----------- || -|| - input - input - Input file that corresponds to || -|| an uncompressed dataset, for a || -|| compression run, or a com- || -|| pressed bitstream, for a decom- || -|| pression run. || -|| || -|| - output - Output - Output file that the com- || -|| pressed bitstream, for a com- || -|| pression run, or reconstructed || -|| dataset, for a decompression || -|| run, is written to. || -|| || -|| FUNCTIONS: || -|| ---------- || -|| || -|| PRIVATE: PUBLIC: || -|| -------- ------- || -|| - get_digit_sep - main || -|| - get_size || -|| - get_dimension || -|| - get_prog_ord || -|| - get_quant_style || -|| || -|| DEVELOPMENT HISTORY: || -|| -------------------- || -|| || -|| Date Author Change Id Release Description Of Change || -|| ---- ------ --------- ------- --------------------- || -|| 13.10.2017 Patrick Vogler B87D120 V 0.1.0 source file created || -|| 26.11.2020 Patrick Vogler B87E7E4 V 0.1.0 Command line tool refac- || -|| tored. || -|| || -|| || -|| ------------------------------------------------------------------------------------------------------ || -|| || -|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || -|| || -|| Redistribution and use in source and binary forms, with or without modification, are permitted || -|| provided that the following conditions are met: || -|| || -|| (1) Redistributions of source code must retain the above copyright notice, this list of || -|| conditions and the following disclaimer. || -|| || -|| (2) Redistributions in binary form must reproduce the above copyright notice, this list || -|| of conditions and the following disclaimer in the documentation and/or other materials || -|| provided with the distribution. || -|| || -|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED || -|| WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A || -|| PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR || -|| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT || -|| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS || -|| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR || -|| TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF || -|| ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || -|| || -\*====================================================================================================================*/ -/**********************************************************************************************************************\ -|| _ _ _ ____ _ _ _ ___ ____ || -|| | |\ | | | | | | \ |___ || -|| | | \| |___ |___ |__| |__/ |___ || -|| || -\**********************************************************************************************************************/ +/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*\ +|| || +|| /$$$$$$$ /$$ /$$ /$$ /$$ || +|| | $$__ $$|__/ | $$ /$ | $$| $$ || +|| | $$ \ $$ /$$ /$$$$$$ | $$ /$$$| $$| $$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ || +|| | $$$$$$$ | $$ /$$__ $$ | $$/$$ $$ $$| $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$ || +|| | $$__ $$| $$| $$ \ $$ | $$$$_ $$$$| $$ \ $$| $$ \ $$| $$ \ $$| $$ \ $$ || +|| | $$ \ $$| $$| $$ | $$ | $$$/ \ $$$| $$ | $$| $$ | $$| $$ | $$| $$ | $$ || +|| | $$$$$$$/| $$| $$$$$$$ | $$/ \ $$| $$ | $$| $$$$$$/| $$$$$$/| $$$$$$$/ || +|| |_______/ |__/ \____ $$ |__/ \__/|__/ |__/ \______/ \______/ | $$____/ || +|| /$$ \ $$ | $$ || +|| | $$$$$$/ | $$ || +|| \______/ |__/ || +|| || +\* -------------------------------------------------------------------------------------------- */ +/** + * @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 + * information use the --help (-h) argument in the command-line or consult the + * appropriate README file. + * */ +/* -------------------------------------------------------------------------------------------- *\ +|| Copyright (c) 2023, High Performance Computing Center - University of Stuttgart || +|| || +|| Redistribution and use in source and binary forms, with or without modification, are || +|| permitted provided that the following conditions are met: || +|| || +|| (1) Redistributions of source code must retain the above copyright notice, this list of || +|| conditions and the following disclaimer. || +|| || +|| (2) Redistributions in binary form must reproduce the above copyright notice, this list || +|| of conditions and the following disclaimer in the documentation and/or other || +|| materials provided with the distribution. || +|| || +|| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS || +|| OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF || +|| MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE || +|| COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, || +|| EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF || +|| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) || +|| HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR || +|| TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, || +|| EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. || +|| || +\*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ +#include #include -#include -#include #include #include #include +#include #include #include #include -#include -#include -#include -#include "bwccmdl.h" #include "eas3.h" +#include "bwc.h" -/**********************************************************************************************************************\ -|| ____ _ ____ ___ ____ _ ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || -|| | __ | | | |__] |__| | | | | |\ | [__ | |__| |\ | | [__ || -|| |__] |___ |__| |__] | | |___ |___ |__| | \| ___] | | | | \| | ___] || -|| || -\**********************************************************************************************************************/ -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This array defines the arguments supported by the bwc command line tool. Each ! -! argument follows the following structure: ! -! ! -! | flag | long name | short name | opt | type | example | description | ! -! ! -! The flag signals if the argument is active, while the opt and type string def- ! -! ine the argument type and wether it is optional. Finally, the example string ! -! is 24 characters long and highlights how the argument is to be used while the ! -! description should be no longer than 1024 and contain the argument description. ! -! Additionally, the description needs to be subdivided into blocks of 50 charac- ! -! ters for formating. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 09.07.2019 Patrick Vogler B87D120 V 0.1.0 Constant created. ! -! 03.05.2021 Patrick Vogler B87E7E4 V 0.1.0 Description updated. ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static bwc_cmdl_args CMDL_ARGS[] = { -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "compress", "c", "arg", "str1", "-c", "Compress a numerical dataset."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "decompress", "d", "arg", "str1", "-d", "Decompress a BigWhoop file."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "analysis", "al", "arg", "lit", "-al", "Analyze the Peak Signal to Noise Ratio (PSNR) and " - "Mean Square Error (MSE) of a decompressed dataset."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "info", "if", "arg", "str1", "-if", "Display the header information of a BigWhoop file."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "help", "h", "arg", "lit", "-h", "Print this help message and exit."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "input", "i", "arg", "str1", "-i /path/to/input", "Valid path to a file that can be parsed/read by " - "this command line tool. For a full list of the " - "supported file extension see the bottom of this " - "message."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "output", "o", "arg", "str1", "-o /path/to/output", "Valid path and filename that defines the output of" - "the (de)compressed dataset. If not defined, the " - "[input] argument is used to generate the (de)com- " - "pressed output."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "reference", "rf", "arg", "str1", "-rf /path/to/output", "Valid path to a file that is used as a reference " - "for the [analysis] option."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "verbose", "v", "opt", "num1", "-v *", "Displays miscellaneous information. This option " - "accepts the value 0 (default) for compression sta-" - "tistics and 1 for the applied compression param. "}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "bitrate", "b", "opt", "numl", "-b *, *, *...", "Defines the quality layers present in the code- " - "stream as a function of the average bits per data " - "point. This option accepts real numbers in the " - "range of 0 < * < 64."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "codeblock_size", "cb", "opt", "num4", "-cb x=* y=* z=* ts=*", "Defines the codeblocks size for all dimensions and" - "timesteps. This option accepts natural numbers in " - "log2 format in the range of 1 <= * <= 10. The sum " - "of all values has to lie within the range of " - "4 < sum* < 20."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "compression_ratio", "cr", "opt", "num1", "-cr *", "Defines the ratio between the uncompresssed and " - "uncompressed file size. This option accepts all " - "positive real numbers."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "decomposition_levels", "dl", "opt", "num4", "-dl x=* y=* z=* ts=*", "Deefines the number of wavelet decompositions ap- " - "plied to all dimensions and timesteps. This option" - "accepts natural numbers in the range of 1 <= * <= " - "63."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "number_of_threads", "n", "opt", "num1", "-n *", "Defines the number of OpenMP threads used to (de) " - "compress the [input] file. This option accepts " - "natural numbers in the range of 1 <= * <= 255. "}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "layer", "l", "opt", "num1", "-l *", "Defines the quality layer used to generate the nu-" - "merical dataset from the bwc codestream. This op- " - "tion accepts natural numbers in the range of 0 < " - "* <= number_of_quality_layers."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{0, "wavelet_kernels", "k", "opt", "str4", "-k x=* y=* z=* ts=*", "Ddefines the wavelet kernels applied to all dimen-" - "sions and timesteps. This option accepts the " - "strings CDF, LeGall and Haar."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{0, "quantisation_step_size", "q", "opt", "num1", "-q *", "Defines the step size of the quantization applied " - "to the wavelet coefficients. This option accepts " - "real numbers in the range of 0 < * < 2."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "q_format_range", "qm", "opt", "num1", "-qm *", "Defines the Q format's number of fractional bits " - "used to transform the floating to a fixed point " - "format. This option accepts natural numbers in the" - "range of 1 <= * <= 62."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "error_resilience", "r", "opt", "lit", "-r", "The [error_resilience] option is used to place " - "special markers in the compressed bitstream that " - "help with error detection and limit error propaga-" - "tion."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "tile_size", "t", "opt", "num4", "-t x=* y=* z=* ts=*", "Defines the tile size for all dimensions and time-" - "steps of a tile. This option accepts natural num- " - "bers in the range of 16 <= * <= domain size."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{1, "precinct_size", "p", "opt", "num4", "-p x=* y=* z=* ts=*", "Defines the precinct size for all dimensions and " - "timesteps. This option accepts natural numbers in " - "log2 format in the range of 1 <= * <= 15."}, -//----|---------------------------|-----|---------|---------|---------------------------|--------------------------------------------------| -{0, "", "", "end", "", "", ""}}; +/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*\ +|| _ _ ____ ____ ____ ____ ____ || +|| |\/| |__| | |__/ | | [__ || +|| | | | | |___ | \ |__| ___] || +|| || +\*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ +/// @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" -/**********************************************************************************************************************\ -|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || -|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || -|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || -|| || -\**********************************************************************************************************************/ -/*----------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function converts the endianess of half, single or double precision values. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! value void* - Memory address of the parame- ! -! ter to be converted. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 30.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! 21.11.2019 Patrick Vogler B87E7E4 V 0.1.0 functionality expanded ! -! to 32 bit integers ! -! 21.11.2019 Patrick Vogler B87E7E4 V 0.1.0 functionality expanded ! -! to 16 bit integers ! -! ! -\*----------------------------------------------------------------------------------------------------------*/ -static void -endian_conversion(void *value, - uint8_t const accuracy) +#define TYPERROR "o##########################################################o\n"\ + "| 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" + +#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 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. + */ +/*===========================================================================|====================*/ +#define remove_deliminator(arg, end, delim) \ +{ \ + for(end = arg; *end; end++) \ + *end = (*end == delim ? ' ' : *end); \ +} +/// @endcond + +/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*\ +|| ____ ____ _ _ ____ ___ ____ _ _ ___ ____ || +|| | | | |\ | [__ | |__| |\ | | [__ || +|| |___ |__| | \| ___] | | | | \| | ___] || +|| || +\*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ +/*================================================================================================*/ +/** + * @details String containing the header used for the cli output. + */ +/*================================================================================================*/ +static char bwc_header_art[] = "==============================================================\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. + */ +/*================================================================================================*/ +const char *argp_program_version = "bwc 0.1.0"; +const char *argp_program_bug_address = "patrick.vogler@hlrs.de"; + +/*================================================================================================*/ +/** + * @details Docummentation string displayed at the start of the help section. + */ +/*================================================================================================*/ +static char doc[] = "\n"\ + "bwc is a simple command line tool that leverages the Big Whoop library to" + " (de)compress a 2- to 4-dimensional IEEE 754 " + "floating point array.\n"\ + "\n"\ + "Available use cases:\n"\ + "\n"\ + " Compression: bwc -C [INPUT] [OPTIONS]\n"\ + " Decompression: bwc -D [INPUT] [OPTIONS]\n"\ + " Analysis: bwc -A [INPUT] -R [REFERENCE]\n"\ + " Information: bwc -H [INPUT]\n"\ + "\n"\ + "Valid Option Values:\n"\ + "\n" + " String that defines: input = path/to/an/input/file.\n" + " String that defines: output = path/to/an/output/file.\n" + "\n" + " Single numerical value: num = *.\n" + " One or more numerical values seperated by commas:\n" + " narr = *,*,...\n" + "\n" + " Numerical values that can be specified globally or for\n" + " all spacial and temporal directions individually:\n" + " ndir = * or ndir = x,y,z,ts.\n"; + /*"\n" + " Single string.\n" + " One or more strings seperated by commas: sarr = *,*,...\n" + " Strings that can be specified globally or for all\n" + " spacial and temporal directions individually:\n" + " sdir = * or sdir = x,y,z,ts.\n"*/ + +//=================================================================================================| +/** + * @details Structure specifing the BigWhoop command line interface options supported by the argp + * parser. + */ +/*================================================================================================*/ +static struct argp_option options[] = { +//--------------------|-----|------------|--------------------|--------------------------------|---| +// long name | key | argument | argp flag | documentation | g | +//--------------------|-----|------------|--------------------|--------------------------------|---| +//====================|=====|============|====================|================================|===| +{0, 0, 0, 0, " [FILE OPTIONS]\n", 1}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"analysis", 'A', "", 0, "Analyze Peak Signal to Noise" + " Ratio (PSNR) and Mean Square" + " Error (MSE) between input and" + " reference file.\n", 1}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"comp", 'C', "", 0, "Compress a numerical dataset.", 1}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"decomp", 'D', "", 0, "Decompress a BigWhoop file.", 1}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"header", 'H', "", 0, "Display the header information" + " of a BigWhoop file.\n", 1}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"output", 'O', "", 0, "Defines output file.", 1}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"reference", 'R', "", 0, "Reference file used for PSNR" + " and MSE calculation.", 1}, +//====================|=====|============|====================|================================|===| +//--------------------|-----|------------|--------------------|--------------------------------|---| +// long name | key | argument | argp flag | documentation | g | +//--------------------|-----|------------|--------------------|--------------------------------|---| +//====================|=====|============|====================|================================|===| +{0, 0, 0, 0, " [LITERAL OPTIONS]\n", 2}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"erresilience", 'e', 0, 0, "Instrument bitstream to allow " + "for error resilient decoding of" + " compressed dataset.\n", 2}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"verbose", 'v', 0, 0, "Display compression statistics " + "and applied compression " + "parameters.", 2}, +//====================|=====|============|====================|================================|===| +//--------------------|-----|------------|--------------------|--------------------------------|---| +// long name | key | argument | argp flag | documentation | g | +//--------------------|-----|------------|--------------------|--------------------------------|---| +//====================|=====|============|====================|================================|===| +{0, 0, 0, 0, " [NUMERICAL OPTIONS]\n", 3}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"bitrate", 'b', "", 0, "Quality layers present in the " + "code-stream as a function of " + "the average bits per data-" + "point. Accepts real numbers in " + "the range of 0 < * < 64.\n", 3}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"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" + "tions applied to the data " + "arrays. Accepts natural numbers" + " in the range of 1 <= * <= 63." + "\n", 3}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"layer", 'l', "", OPTION_HIDDEN, "Quality layer used to recon" + "struct the numerical data set. " + "Accepts natural numbers in the " + "range of 0 < * <= number_of_" + "quality_layers.\n", 3}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"nthreads", 'n', "", 0, "Number of OpenMP threads used " + "to (de)compress the " + "file. Accepts natural numbers " + "in the range of 1 <= * <= 255." + "\n", 3}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"precinct", 'p', "", OPTION_HIDDEN, "Precinct size in log2 format. " + "Accepts natural numbers in the" + " range of 1 <= * <= 15.\n", 3}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"qstep", 'q', "", OPTION_HIDDEN, "Quantization step size applied " + "to the wavelet coefficients. " + "Accepts real numbers in the " + "range of 0 < * < 2.\n", 3}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"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" + "presssed and compressed file " + "size. Accepts positive real " + "numbers.\n", 3}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"tile", 't', "", 0, "Size of tiles the dataset is " + "subdivided into. Accepts " + "natural numbers in the range " + "of 16 <= * <= domain size.", 3}, +//====================|=====|============|====================|================================|===| +//--------------------|-----|------------|--------------------|--------------------------------|---| +// long name | key | argument | argp flag | documentation | g | +//--------------------|-----|------------|--------------------|--------------------------------|---| +//====================|=====|============|====================|================================|===| +//{0, 0, 0, 0, " [NUMERICAL OPTIONS]\n", 4}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{"wkernels", 'k', "", OPTION_HIDDEN, "Wavelet kernels applied along " + "spatial and temporal aixs. " + "Accepts the strings CDF, LeGall" + " and Haar.", 4}, +//--------------------|-----|------------|--------------------|--------------------------------|---| +{0} +}; + +//=================================================================================================| +/** + * @details Constants used to signal the command_line interface mode. + */ +/*=====================================================|==========================================*/ +typedef enum +{ + cli_ini, //!< Undefined command line mode + cli_cmp, //!< Compression run + cli_dcp, //!< Decompression run + cli_anl, //!< Analyse distortion of reconstr. file + cli_inf, //!< Display BWC Header Information +} cli_mode; + +/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*\ +|| ___ ____ ____ ____ _ _ _ ____ ___ ___ _ _ ___ ____ ____ || +|| | \ |___ |__/ |__/ | | | |___ | \ | \_/ |__] |___ [__ || +|| |__/ |___ | \ | \ | \/ |___ |__/ | | | |___ ___] || +|| || +\*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ +/*================================================================================================*/ +/** + * @details Structure used to store the user supplied command-line options and arguments. + */ +/*===========================|=========================|==========================================*/ +typedef struct +{ + char *args[2]; + cli_mode mode; //!< Current state of the cli tool + uint16_t optSet; //!< Flag signaling witch opt has been set + + char *in, *out, *ref; //!< Name of the in/out/ref file + + bool erresilience; //!< Flag signalling error resilience + bool verbose; //!< Flag signalling verbose output + + 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; + + +/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*\ +|| ___ ____ _ _ _ ____ ___ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || +|| |__] |__/ | | | |__| | |___ |___ | | |\ | | | | | | |\ | [__ || +|| | | \ | \/ | | | |___ | |__| | \| |___ | | |__| | \| ___] || +|| || +\*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ +/*================================================================================================*/ +/** + * @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 ASSERTIONS: ! + ! DEFINE CHAR VARIABLES: ! \*-----------------------*/ - assert(value); + char *parse; - switch(accuracy) + remove_deliminator(arg, parse, deliminator); + + for(parse = arg; *parse; parse++) { - case 2: + if (decimal == true) { - uint16_t *tmp = (uint16_t*)value; - - *tmp = (uint16_t)( *tmp << 8) | - (uint16_t)( *tmp >> 8); - break; + if (!isdigit(*parse) && *parse != ' ' && *parse != '.') + return EXIT_FAILURE; } - - case 4: + else { - uint32_t *tmp = (uint32_t*)value; - - *tmp = (uint32_t)((*tmp << 8) & 0xFF00FF00) | - (uint32_t)((*tmp >> 8) & 0x00FF00FF); - - *tmp = (uint32_t)( *tmp << 16) | - (uint32_t)( *tmp >> 16); - break; - } - - case 8: - { - uint64_t *tmp = (uint64_t*)value; - - *tmp = (uint64_t)((*tmp << 8) & 0xFF00FF00FF00FF00ULL) | - (uint64_t)((*tmp >> 8) & 0x00FF00FF00FF00FFULL); - - *tmp = (uint64_t)((*tmp << 16) & 0xFFFF0000FFFF0000ULL) | - (uint64_t)((*tmp >> 16) & 0x0000FFFF0000FFFFULL); - - *tmp = (uint64_t)( *tmp << 32) | - (uint64_t)( *tmp >> 32); - break; - } - default: - { - break; + if (!isdigit(*parse) && *parse != ' ') + return EXIT_FAILURE; } } + return EXIT_SUCCESS; } -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function takes a command line argument, checks if it is hyphenated and, ! -! if true, returns a pointer to the first valid character in the string. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! str char* - String containing a command ! -! line argument. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! char* - Pointer to a hyphenated com- ! -! mand line argument. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 03.05.2021 Patrick Vogler B87D120 V 0.1.0 function created ! -! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static char* -get_opt(char* str) +/*================================================================================================*/ +/** + * @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. + * @param[in,out] state Struct containing useful information about the current parsing state. + * + * @retval -1 Error + * @retval 0 OK + */ +/*================================================================================================*/ +static error_t +parse_opt(int key, + char *arg, + struct argp_state *state) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ - size_t trim; + int64_t buff; + uint8_t i; - trim = strspn(str, " "); - - if((trim < strlen(str)) && (str[trim] == '-')) - return &str[trim]; - else - return NULL; -} - -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function takes an integer value, generates a version with proper digital ! -! group separators and returns the string to the function caller. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! integer unsigned int(64 bit) - Integer value. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! char* - Character array containing the ! -! group seperated integer value. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 03.02.2020 Patrick Vogler B87D120 V 0.1.0 function created ! -! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static char* -get_digit_sep(uint64_t integer) -{ /*-----------------------*\ - ! DEFINE INT VARIABLES: ! + ! DEFINE REAL VARIABLES: ! \*-----------------------*/ - uint64_t multiplier; - uint16_t buffI; - uint8_t length, shift; + double compRatio; + double qt_step_size; + float bitrate; /*-----------------------*\ ! DEFINE CHAR VARIABLES: ! \*-----------------------*/ - char buffC[7] = {0}; - char *str; + char *end; + char *token, *ptr; - /*--------------------------------------------------------*\ - ! Calculate the decimal power of the integer value, esti- ! - ! mate the length of the group seperated string and alloc- ! - ! cate the corresponding character array. ! - \*--------------------------------------------------------*/ - shift = (uint8_t)log10(integer); - length = (uint8_t)floor(shift/3.0f) + shift + 2; + /*-----------------------*\ + ! DEFINE STRUCTS: ! + \*-----------------------*/ + cli_arguments *arguments; - str = calloc(length, sizeof(char)); - if(str == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return NULL; - } + /*-----------------------*\ + ! DEFINE ASSERTIONS: ! + \*-----------------------*/ + assert(state); - /*--------------------------------------------------------*\ - ! Iterate over the integer value and assemble the group ! - ! serparated string. ! - \*--------------------------------------------------------*/ - do + /* Save frequently used variables/structures to * + * temporary variables. */ + arguments = state->input; + + /* Parse the cli arguments. */ + switch(key) { - /*--------------------------------------------------------*\ - ! If the first digits do not form a group, decrement the ! - ! shift to the next group, extract the first digits from ! - ! the integer and write them to the string. ! - \*--------------------------------------------------------*/ - if(shift % 3 || shift == 0) + /* Ingest compression argument. */ + case 'C': { - shift -= (shift % 3); - multiplier = (uint64_t)pow(10, shift); - buffI = integer/multiplier; - integer -= (uint64_t)buffI * multiplier; - - sprintf(buffC, "%d", buffI); - strcat(str, buffC); - memset(buffC, '\0', 5); - } - /*--------------------------------------------------------*\ - ! If the next digits form a group, decrement the decimal ! - ! shift, extract digits from the integer and write them ! - ! to the string with the proper separator. ! - \*--------------------------------------------------------*/ - else - { - shift -= 3; - multiplier = (uint64_t)pow(10, shift); - buffI = integer/multiplier; - integer -= (uint64_t)buffI * multiplier; - if(strlen(str)) + if (arguments->mode != cli_ini) { - sprintf(buffC, ".%03d", buffI); + 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 { - sprintf(buffC, "%03d", buffI); + arguments->mode = cli_cmp; + arguments->in = arg; } - strcat(str, buffC); - memset(buffC, '\0', 5); - } - } while(shift); - return str; -} - -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function takes an integer value and generates a version with the appropri- ! -! ate byte unit in log2 format that is returned to the function caller. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! integer unsigned int(64 bit) - Integer value. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! char* - Character array containing ! -! the group seperated string. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 03.05.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static char* -get_size(uint64_t integer) -{ - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64_t multiplier; - uint8_t i; - - /*-----------------------*\ - ! DEFINE CHAR VARIABLES: ! - \*-----------------------*/ - char *sizes[] = { "EiB", "PiB", "TiB", "GiB", "MiB", "KiB", "B" }; - char *str; - - /*--------------------------------------------------------*\ - ! Set up the multiplier used to evaluate the digital unit ! - ! prefix and allocate the character array returned to the ! - ! function caller. ! - \*--------------------------------------------------------*/ - multiplier = 1024ULL * 1024ULL * 1024ULL * - 1024ULL * 1024ULL * 1024ULL; - - str = calloc(10, sizeof(char)); - if(str == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return NULL; - } - - /*--------------------------------------------------------*\ - ! If larger than 0, iterate over the byte units until the ! - ! integer is within its range and populate the char. array ! - ! with the appropriate information. ! - \*--------------------------------------------------------*/ - if(integer > 0) - { - for(i = 0; i < 7; ++i, multiplier /= 1024) - { - if(integer < multiplier) - continue; - if(integer % multiplier == 0) - sprintf(str, "%" PRIu64 " %s", integer / multiplier, sizes[i]); - else - sprintf(str, "%.1f %s", floor((10.0 * integer) / multiplier) / 10.0, sizes[i]); break; } - } - else - { - strcpy(str, "0 B"); - } - return str; -} - -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function is a variant of the DJB hash function that takes a string, con- ! -! verts it to uppercase and returns the appropriate hash. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! str char* - String used to generate a u- ! -! niquely identifiable hash. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! uint64_t - Uniquely identifiable hash. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 17.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static uint64_t -hash(char* str) -{ - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64_t hash; - uint8_t c; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(str); - - /*--------------------------------------------------------*\ - ! Initialize the hash with a magic number. ! - \*--------------------------------------------------------*/ - hash = 0x1505; - - /*--------------------------------------------------------*\ - ! Walk through all the characters in the string, convert ! - ! them to uppercase and use them to generate the hash. ! - \*--------------------------------------------------------*/ - while((c = *str++)) - { - if((c >= 97) && - (c <= 122)) + /* Ingest decompression argument. */ + case 'D': { - c = c - 32; - } - - hash = (hash * 33) ^ c; - } - - /*--------------------------------------------------------*\ - ! Return the hash. ! - \*--------------------------------------------------------*/ - return hash; -} - -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function deallocates a util_arg_node linked list that is used to store ! -! the bwc command line arguments. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! args util_arg_node* - Arguments/options linked list ! -! for the bwc command-line tool. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 24.04.2019 Patrick Vogler B87D120 V 0.1.0 Function created ! -! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static void -bwc_kill_arg(bwc_cmdl_arg_node *args) -{ - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_cmdl_arg_node *temp; - - if(args != NULL) - { - /*--------------------------------------------------------*\ - ! Reset the arguments linked list to its root node. ! - \*--------------------------------------------------------*/ - args = args->root; - - /*--------------------------------------------------------*\ - ! Walk through the arguments linked list and deallocate ! - ! the lit_opt, num_ opt and util_arg_node structure. ! - \*--------------------------------------------------------*/ - while(args != NULL) - { - temp = args; - args = args->next; - - free(temp->lit_opt); - free(temp->num_opt); - free(temp); - } - } -} - -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function is used to parse the command-line arguments, check if they are ! -! valid arguments and options for the bwc command-line tool and save them in a ! -! linked list. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! argc int - Argument count ! -! ! -! argv char** - Argument vector ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! util_arg_node* - Arguments/options linked list ! -! for the bwc command-line tool. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 17.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static bwc_cmdl_arg_node* -parse_arguments(int argc, - char **argv) -{ - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64_t buf; - uint64_t *hash_list; - uint64_t *tmp; - - uint16_t l, lsiz; - - uint8_t i, j; - - /*-----------------------*\ - ! DEFINE CHAR VARIABLES: ! - \*-----------------------*/ - char *token, *ptr; - char *str; - - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_cmdl_arg_node *args; - - /*--------------------------------------------------------*\ - ! Allocate an integer array used to store the hash values ! - ! for all active command line arguments and options. ! - \*--------------------------------------------------------*/ - hash_list = calloc(40, sizeof(uint64_t)); - if(hash_list == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return NULL; - } - - /*--------------------------------------------------------*\ - ! Loop through the command line argument list and store ! - ! the hash value of the long and short name for all active ! - ! command line arguments in the hash list. ! - \*--------------------------------------------------------*/ - for(l = 0, lsiz = 20; strcmp(CMDL_ARGS[l].arg_type, "end"); ++l) - { - if(l >= lsiz) - { - lsiz *= 2; - hash_list = realloc(hash_list, lsiz * 2 * sizeof(uint64_t)); - if(hash_list == NULL) + if (arguments->mode != cli_ini) { - // memory allocation error - fprintf(stderr, MEMERROR); - return NULL; + 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; } - hash_list[2 * l] = hash(CMDL_ARGS[l].arg_long); - hash_list[2 * l + 1] = hash(CMDL_ARGS[l].arg_short); - } - - /*--------------------------------------------------------*\ - ! Save the total number of active command line arguments, ! - ! reallocate the corresponding hash list and initialize ! - ! the arguments linked list. ! - \*--------------------------------------------------------*/ - lsiz = l; - tmp = realloc(hash_list, lsiz * 2 * sizeof(uint64_t)); - if(tmp == NULL) - { - // memory allocation error - free(hash_list); - fprintf(stderr, MEMERROR); - return NULL; - } - else - { - hash_list = tmp; - } - - args = calloc(1, sizeof(bwc_cmdl_arg_node)); - if(args == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return NULL; - } - args->root = args; - - /*--------------------------------------------------------*\ - ! Walk through all the command-line arguments passed to ! - ! main. ! - \*--------------------------------------------------------*/ - for(i = 0; i < argc; ++i) - { - /*--------------------------------------------------------*\ - ! Check if the command-line argument is hyphenated, indi- ! - ! cating a bwc argument or option. If this is the case, ! - ! save a pointer to the argument in a temporary variable. ! - \*--------------------------------------------------------*/ - str = get_opt(argv[i]); - - if(str) + /* Ingest analysis argument. */ + case 'A': { - /*--------------------------------------------------------*\ - ! Generate a hash from the argument string. ! - \*--------------------------------------------------------*/ - buf = hash(++str); - - /*--------------------------------------------------------*\ - ! Check if the command-line argument is a valid bwc argu- ! - ! ment or option and if additional values are expected for ! - ! the current argument or option. The additional values ! - ! are handled according to the type of the current argu- ! - ! ment. ! - \*--------------------------------------------------------*/ - for(l = 0; l < lsiz; ++l) + if (arguments->mode != cli_ini) { - if(buf == hash_list[2 * l] || buf == hash_list[2 * l + 1]) + 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; + } + + /* Ingest header info argument. */ + case 'H': + { + 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; + } + + /* Ingest output argument. */ + case 'O': + { + 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; + } + + /* Ingest reference argument. */ + case 'R': + { + 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->verbose = true; + break; + } + + /* Ingest bit rates. */ + case 'b': + { + 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 deliminator 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) { - switch(hash(CMDL_ARGS[l].type)) - { - /*--------------------------------------------------------*\ - ! This type of argument/option requires no additional in- ! - ! formation and the parser can advance to the next hyphen- ! - ! ated command-line argument. ! - \*--------------------------------------------------------*/ - case 0x000000000B87DB14: - { - /*--------------------------------------------------------*\ - ! Store the hash identifier in the linked list node. ! - \*--------------------------------------------------------*/ - args->hash = hash_list[2 * l]; - break; - } - - /*--------------------------------------------------------*\ - ! This type of argument/option accepts a single string ! - ! that is passed to the parser as a non-hyphenated ! - ! command-line argument. ! - \*--------------------------------------------------------*/ - case 0x000000017C8A3F41: - { - /*--------------------------------------------------------*\ - ! Store the hash identifier in the linked list node. ! - \*--------------------------------------------------------*/ - args->hash = hash_list[2 * l]; - - /*--------------------------------------------------------*\ - ! Check that the next command-line argument is non-hypenat-! - ! ed. If true, allocate the lit_opt character array and ! - ! store the arguments memory handle. ! - \*--------------------------------------------------------*/ - if(((i + 1) < argc) && (get_opt(argv[i + 1]) == NULL)) - { - args->lit_opt = calloc(args->count + 1, sizeof(char*)); - if(args->lit_opt == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - bwc_kill_arg(args); - free(hash_list); - return NULL; - } - args->lit_opt[args->count++] = argv[i + 1]; - } - break; - } - - /*--------------------------------------------------------*\ - ! This type of argument/option accepts four additional ! - ! strings that are passed to parser as a non-hyphenated ! - ! command-line arguments. ! - \*--------------------------------------------------------*/ - case 0x000000017C8A3F44: - { - /*--------------------------------------------------------*\ - ! Store the hash identifier in the linked list node. ! - \*--------------------------------------------------------*/ - args->hash = hash_list[2 * l]; - - /*--------------------------------------------------------*\ - ! Loop through the next four command-line arguments, check ! - ! that they are non-hyphenated and, if true, store their ! - ! memory handle in the list node. ! - \*--------------------------------------------------------*/ - for(j = i + 1; j < argc && (get_opt(argv[j]) == NULL); ++j) - { - /*--------------------------------------------------------*\ - ! Allocate the lit_opt array for 4 character strings. ! - \*--------------------------------------------------------*/ - if(args->lit_opt == NULL) - { - args->lit_opt = calloc(4, sizeof(char*)); - if(args->lit_opt == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - bwc_kill_arg(args); - free(hash_list); - return NULL; - } - args->count = 0x04; - } - - /*--------------------------------------------------------*\ - ! Save the memory handle for the next argument in a tempo- ! - ! rary variable and tokenize the string according to the ! - ! specified delimiters. ! - \*--------------------------------------------------------*/ - str = argv[j]; - token = strtok_r(str, ":=\t, ", &ptr); - - /*--------------------------------------------------------*\ - ! Check if a valid token has been generated for the first ! - ! spatial direction. If true, save the memory handle, set ! - ! the dimension flag and generate the next token. ! - \*--------------------------------------------------------*/ - if(token && ((strchr(token, 'x') != NULL) || - (strchr(token, 'X') != NULL))) - { - token = strtok_r(NULL, ":=\t, ", &ptr); - args->lit_opt[0] = token; - args->dim |= 0x01; - token = strtok_r(NULL, ":=\t, ", &ptr); - } - - /*--------------------------------------------------------*\ - ! Check if a valid token has been generated for the second ! - ! spatial direction. If true, save the memory handle, set ! - ! the dimension flag and generate the next token. ! - \*--------------------------------------------------------*/ - if(token && ((strchr(token, 'y') != NULL) || - (strchr(token, 'Y') != NULL))) - { - token = strtok_r(NULL, ":=\t, ", &ptr); - args->lit_opt[1] = token; - args->dim |= 0x02; - token = strtok_r(NULL, ":=\t, ", &ptr); - } - - /*--------------------------------------------------------*\ - ! Check if a valid token has been generated for the third ! - ! spatial direction. If true, save the memory handle, set ! - ! the dimension flag and generate the next token. ! - \*--------------------------------------------------------*/ - if(token && ((strchr(token, 'z') != NULL) || - (strchr(token, 'Z') != NULL))) - { - token = strtok_r(NULL, ":=\t, ", &ptr); - args->lit_opt[2] = token; - args->dim |= 0x04; - token = strtok_r(NULL, ":=\t, ", &ptr); - } - - /*--------------------------------------------------------*\ - ! Check if a valid token has been generated for the first ! - ! temporal direction. If true, save the memory handle, set ! - ! the dimension flag and generate the next token. ! - \*--------------------------------------------------------*/ - if(token && ((strchr(token, 't') != NULL) || - (strchr(token, 'T') != NULL))) - { - token = strtok_r(NULL, ":=\t, ", &ptr); - args->lit_opt[3] = token; - args->dim |= 0x08; - token = strtok_r(NULL, ":=\t, ", &ptr); - } - } - break; - } - - /*--------------------------------------------------------*\ - ! This type of argument/option accepts a single numerical ! - ! value that is passed to parser as a non-hyphenated com- ! - ! mand-line argument. ! - \*--------------------------------------------------------*/ - case 0x000000017C82A8C2: - { - /*--------------------------------------------------------*\ - ! Store the hash identifier in the linked list node. ! - \*--------------------------------------------------------*/ - args->hash = hash_list[2 * l]; - - /*--------------------------------------------------------*\ - ! Check that the next command-line argument is non-hypenat-! - ! ed and a valid floating point value. If true, allocate ! - ! the num_opt array and store the real value in it. ! - \*--------------------------------------------------------*/ - if(((i + 1) < argc) && (get_opt(argv[i + 1]) == NULL)) - { - str = argv[i + 1]; - - if(strtof(str, NULL) > 0.0f) - { - args->num_opt = calloc(args->count + 1, sizeof(double)); - if(args->num_opt == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - bwc_kill_arg(args); - free(hash_list); - return NULL; - } - args->num_opt[args->count++] = strtof(str, NULL); - } - } - break; - } - - /*--------------------------------------------------------*\ - ! This type of argument/option accepts four additional nu- ! - ! merical values that are passed to parser as a non-hyphen-! - ! ated command-line arguments. ! - \*--------------------------------------------------------*/ - case 0x000000017C82A8C7: - { - /*--------------------------------------------------------*\ - ! Store the hash identifier in the linked list node. ! - \*--------------------------------------------------------*/ - args->hash = hash_list[2 * l]; - - /*--------------------------------------------------------*\ - ! Loop through the next four command-line arguments, check ! - ! that they are non-hyphenated and, if true, store their ! - ! numerical values handle in the list node. ! - \*--------------------------------------------------------*/ - for(j = i + 1; j < argc && (get_opt(argv[j]) == NULL); ++j) - { - /*--------------------------------------------------------*\ - ! Allocate the num_opt array for 4 real values. ! - \*--------------------------------------------------------*/ - if(args->num_opt == NULL) - { - args->num_opt = calloc(4, sizeof(double)); - if(args->num_opt == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - bwc_kill_arg(args); - free(hash_list); - return NULL; - } - args->count = 0x04; - } - - /*--------------------------------------------------------*\ - ! Save the memory handle for the next argument in a tempo- ! - ! rary variable and tokenize the string according to the ! - ! specified delimiters. ! - \*--------------------------------------------------------*/ - str = argv[j]; - token = strtok_r(str, ":=\t, ", &ptr); - - /*--------------------------------------------------------*\ - ! Check if a valid token has been generated for the first ! - ! spatial direction. If true, save the numerical value, ! - ! set the dimension flag and generate the next token. ! - \*--------------------------------------------------------*/ - if(token && ((strchr(token, 'x') != NULL) || - (strchr(token, 'X') != NULL))) - { - token = strtok_r(NULL, ":=\t, ", &ptr); - if(token != NULL) - { - args->num_opt[0] = strtof(token, NULL); - args->dim |= 0x01; - } - token = strtok_r(NULL, ":=\t, ", &ptr); - } - - /*--------------------------------------------------------*\ - ! Check if a valid token has been generated for the second ! - ! spatial direction. If true, save the numerical value, ! - ! set the dimension flag and generate the next token. ! - \*--------------------------------------------------------*/ - if(token && ((strchr(token, 'y') != NULL) || - (strchr(token, 'Y') != NULL))) - { - token = strtok_r(NULL, ":=\t, ", &ptr); - if(token != NULL) - { - args->num_opt[1] = strtof(token, NULL); - args->dim |= 0x02; - } - token = strtok_r(NULL, ":=\t, ", &ptr); - } - - /*--------------------------------------------------------*\ - ! Check if a valid token has been generated for the third ! - ! spatial direction. If true, save the numerical value, ! - ! set the dimension flag and generate the next token. ! - \*--------------------------------------------------------*/ - if(token && ((strchr(token, 'z') != NULL) || - (strchr(token, 'Z') != NULL))) - { - token = strtok_r(NULL, ":=\t, ", &ptr); - if(token != NULL) - { - args->num_opt[2] = strtof(token, NULL); - args->dim |= 0x04; - } - token = strtok_r(NULL, ":=\t, ", &ptr); - } - - /*--------------------------------------------------------*\ - ! Check if a valid token has been generated for the first ! - ! temporal direction. If true, save the numerical value, ! - ! set the dimension flag and generate the next token. ! - \*--------------------------------------------------------*/ - if(token && ((strchr(token, 't') != NULL) || - (strchr(token, 'T') != NULL))) - { - token = strtok_r(NULL, ":=\t, ", &ptr); - if(token != NULL) - { - args->num_opt[3] = strtof(token, NULL); - args->dim |= 0x08; - } - token = strtok_r(NULL, ":=\t, ", &ptr); - } - } - break; - } - - /*--------------------------------------------------------*\ - ! This type of argument/option accepts one ore more numeri-! - ! cal values that are passed to parser as a non-hyphenated ! - ! command-line arguments. ! - \*--------------------------------------------------------*/ - case 0x000000017C82A8BF: - { - /*--------------------------------------------------------*\ - ! Store the hash identifier in the linked list node. ! - \*--------------------------------------------------------*/ - args->hash = hash_list[2 * l]; - - /*--------------------------------------------------------*\ - ! Loop through the next command-line arguments that are ! - ! non-hyphenated and store their numerical values handle ! - ! in the list node. ! - \*--------------------------------------------------------*/ - for(j = i + 1; j < argc && (get_opt(argv[j]) == NULL); ++j) - { - /*--------------------------------------------------------*\ - ! Save the memory handle for the next argument in a tempo- ! - ! rary variable and tokenize the string according to the ! - ! specified delimiters. ! - \*--------------------------------------------------------*/ - str = argv[j]; - token = strtok_r(str, ", ", &ptr); - - /*--------------------------------------------------------*\ - ! Check if a valid token has been generated. If true, re- ! - ! size the num_opt array, save the numerical value, and ! - ! generate the next token. ! - \*--------------------------------------------------------*/ - for(; (token != NULL); token = strtok_r(NULL, ", ", &ptr)) - { - if(token != NULL) - { - if(strtof(token, NULL) > 0.0f) - { - args->num_opt = realloc(args->num_opt, (args->count + 1) * sizeof(double)); - if(args->num_opt == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - bwc_kill_arg(args); - free(hash_list); - return NULL; - } - args->num_opt[args->count++] = strtof(token, NULL); - } - } - } - } - break; - } - - default: - { - continue; - } - } - /*--------------------------------------------------------*\ - ! Allocate and initialize the next linked list node. ! - \*--------------------------------------------------------*/ - args->next = calloc(1, sizeof(bwc_cmdl_arg_node)); - if(args->next == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - bwc_kill_arg(args); - free(hash_list); - return NULL; - } - args->next->root = args->root; - args = args->next; + arguments->rate[i] = (double) bitrate; + } + else + { + errno = 0; + argp_error(state, "The specified bitrate (%f) is " + "out of the supported range.\n", bitrate); } } + + arguments->optSet |= BITRT; + break; } - } - /*--------------------------------------------------------*\ - ! Free the command line argument hash list and return the ! - ! linked list to the function caller. ! - \*--------------------------------------------------------*/ - free(hash_list); - return args; -} -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function is used to parse the util_arg_node linked list and, if it is pre- ! -! sent in linked list, return the memory handle to the bwc argument/option short- ! -! /long-name supplied by the function. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! args util_arg_node* - Arguments/options linked list ! -! for the bwc command-line tool. ! -! ! -! str char* - Long-/short-name of a bwc com- ! -! mand-line argument or option. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! util_arg_nodes* - Memory handle bwc argument ! -! linked list node. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 24.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! 04.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static bwc_cmdl_arg_node* -retrieve_arg(bwc_cmdl_arg_node *const args, - char* name) -{ - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64_t arg_hash; - - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_cmdl_arg_node *temp; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(args); - assert(name); - - /*--------------------------------------------------------*\ - ! Generate a hash from the argument/option name and save ! - ! the root node memory address in a temporary variable. ! - \*--------------------------------------------------------*/ - arg_hash = hash(name); - temp = args->root; - - /*--------------------------------------------------------*\ - ! Advance through the linked list until the argument/op- ! - ! tion, corresponding to the supplied name, has been found ! - ! or the end of the list has been reached. ! - \*--------------------------------------------------------*/ - while(temp->hash != arg_hash && temp->next != NULL) - temp = temp->next; - - /*--------------------------------------------------------*\ - ! If found, return the memory handle to the argument/op- ! - ! option to the function caller. ! - \*--------------------------------------------------------*/ - if((temp->next != NULL) && (temp->hash == arg_hash)) - return temp; - else - return NULL; -} - -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function prints the help page to the standard output. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! - - - ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 14.05.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! 03.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static void -print_help(void) -{ - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint16_t i; - - /*-----------------------*\ - ! DEFINE CHAR VARIABLES: ! - \*-----------------------*/ - char *buf; - - /*--------------------------------------------------------*\ - ! Write the head of the help message to the standard out- ! - ! put. ! - \*--------------------------------------------------------*/ - printf("Usage: bwc [arguments] [file] [options] (De)compress a specified [file] using [options]. \n"\ - " \n"\ - "e.g.: bwc -c -i [input] -o [output] [options] Compress an [input] file with the specified [op- \n"\ - " tions] and save the compressed bitstream in the \n"\ - " [output] file. \n"\ - " \n"\ - "e.g.: bwc -c [input] [options] Compress an [input] file with the specified [op- \n"\ - " tions] and save the compressed bitstream. \n"\ - " \n"\ - "e.g.: bwc -d -i [input] -o [output] [options] Decompress an [input] file with the specified [op-\n"\ - " tions] and save the decompressed bitstream in the \n"\ - " [output] file. \n"\ - " \n"\ - "e.g.: bwc -d [input] [options] Decompress an [input] file with the specified [op-\n"\ - " tions] and save the decompressed bitstream. \n"\ - " \n"\ - "e.g.: bwc -al -i [input] -ref [reference] Evaluate the Peak-Signal-to-Noise-Ratio of the \n"\ - " [input] file with regards to the [reference] file \n"\ - " and print the result to the standard output. \n"\ - " \n"\ - "e.g.: bwc -if -i [input] Print the header information of the compressed \n"\ - " [input] file to the standard output. \n"\ - " \n"\ - " \n"\ - "Arguments: \n"\ - " \n"\ - " [Type] [Usage] [Description] \n"\ - " \n"); - - /*--------------------------------------------------------*\ - ! Loop through the command line arguments list and write ! - ! the short and long name, usage example and description ! - ! for all mandatory (arg) command line arguments to stdout.! - \*--------------------------------------------------------*/ - for(i = 0; strcmp(CMDL_ARGS[i].arg_type, "end"); ++i) - { - if(strcmp(CMDL_ARGS[i].arg_type, "arg") == 0 && CMDL_ARGS[i].active) + /* Ingest codeblock size. */ + case 'c': { - printf(" -%s,\t", CMDL_ARGS[i].arg_short); - printf("--%-24s", CMDL_ARGS[i].arg_long); - printf("%-24s", CMDL_ARGS[i].usage); - printf("%.50s\n", CMDL_ARGS[i].definition); - - for(buf = CMDL_ARGS[i].definition + 50; strcmp(buf, ""); buf += 50) + if (arguments->optSet & CBLKS) { - printf("%58s%.50s\n", "", buf); + argp_error(state, "The codeblock size can only be defined once.\n"); } - printf("\n"); - } - } - - /*--------------------------------------------------------*\ - ! Write the head of the optional arguments list to the ! - ! standard output. ! - \*--------------------------------------------------------*/ - printf("Options: \n"\ - " \n"\ - " [Type] [Usage] [Description] \n"\ - " \n"); - - /*--------------------------------------------------------*\ - ! Loop through the command line arguments list and write ! - ! the short and long name, usage example and description ! - ! for all optional (arg) command line arguments to stdout. ! - \*--------------------------------------------------------*/ - for(i = 0; strcmp(CMDL_ARGS[i].arg_type, "end"); ++i) - { - if(strcmp(CMDL_ARGS[i].arg_type, "opt") == 0 && CMDL_ARGS[i].active) - { - printf(" -%s,\t", CMDL_ARGS[i].arg_short); - printf("--%-24s", CMDL_ARGS[i].arg_long); - printf("%-24s", CMDL_ARGS[i].usage); - printf("%.50s\n", CMDL_ARGS[i].definition); - - for(buf = CMDL_ARGS[i].definition+50; strcmp(buf, ""); buf += 50) + if (verify_opt(arg, ',', false) == EXIT_FAILURE) { - printf("%58s%.50s\n", "", buf); - } - - printf("\n"); - } - } -} - -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function prints the header information of a compressed dataset to the ! -! standard output. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! args util_arg_node* - Arguments/options linked list ! -! for the bwc command-line tool. ! -! ! -! name char* - Long-/short-name of a bwc com- ! -! mand-line argument or option. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! - - ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 12.09.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! 17.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static void -output_info(bwc_cmdl_arg_node *const args, - char* name) -{ - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64_t data_points; - - uint64_t Ld; - uint32_t Ls; - uint16_t Lh; - - uint32_t t; - uint8_t l, p; - - uint16_t marker; - uint8_t index; - - /*-----------------------*\ - ! DEFINE FLOAT VARIABLES: ! - \*-----------------------*/ - bwc_float minVal, maxVal; - - /*-----------------------*\ - ! DEFINE CHAR VARIABLES: ! - \*-----------------------*/ - char *buff; - uchar status; - - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_field *field; - bwc_data *data; - - bwc_gl_ctrl *control; - bwc_gl_inf *info; - - bwc_param_inf *param_info; - - bwc_cmdl_arg_node *temp; - - struct stat buf; - - /*-----------------------*\ - ! DEFINE FILE POINTER: ! - \*-----------------------*/ - FILE *fp; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(args); - - /*--------------------------------------------------------*\ - ! Retrieve the file argument from the linked list and con- ! - ! firm that only one file has been specified and that it ! - ! is a regular file. If true, open the file for reading. ! - \*--------------------------------------------------------*/ - temp = retrieve_arg(args, name); - if((temp == NULL) || - (temp->lit_opt == NULL) || - (temp->lit_opt[0] == NULL)) - { - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: File |\n"\ - "| |\n"\ - "| No File has been specified. |\n"\ - "| |\n"\ - "o##########################################################o\n"); - return; - } - - if(temp->count > 1) - { - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: File |\n"\ - "| |\n"\ - "| More than one file has been specified. |\n"\ - "| |\n"\ - "o##########################################################o\n"); - return; - } - - stat(temp->lit_opt[0], &buf); - if(!S_ISREG(buf.st_mode)) - { - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: file |\n"\ - "| |\n"\ - "| The specified input is not a regular file. |\n"\ - "| |\n"\ - "o##########################################################o\n"); - return; - } - - fp = fopen(temp->lit_opt[0], "rb"); - if(fp == NULL) - { - // error opening file - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: Could not open or read %-25s|\n"\ - "o##########################################################o\n", temp->lit_opt[0]); - return; - } - - /*--------------------------------------------------------*\ - ! Initialize the codestream status and reading index var- ! - ! iables and parse the codestream to evaluate the size of ! - ! the main header. ! - \*--------------------------------------------------------*/ - status = CODESTREAM_OK; - index = 0; - - while(status == 0) - { - Ld = fread(&marker, sizeof(uint16_t), 1, fp); - endian_conversion(&marker, 2); - if((Ld != 1) || (marker < 0xFF00)) - { - // Invalid Codestream - fprintf(stderr, CSTERROR); - fclose(fp); - return; - } - - switch(marker) - { - case SOC: - { - break; + argp_error(state, "Invalid deliminator in the codeblock" + " size option.\n"); } - case COM: - case SGC: - case SGI: - default: + for(buff = strtoll(arg, &end, 10), i = 0; arg != end && i < 4; + buff = strtoll(arg, &end, 10), i++) { - if(fread(&Lh, sizeof(uint16_t), 1, fp) != 1) + arg = end; + + if (buff >= 0 && buff <= 10 && errno != ERANGE) { - // Invalid Codestream - fprintf(stderr, CSTERROR); - fclose(fp); - return; + arguments->cblkSize[i] = (uint8_t) buff; } - - endian_conversion(&Lh, 2); - fseek(fp, Lh - 2, SEEK_CUR); - - break; - } - - case SAX: - { - if(fread(&Ls, sizeof(uint32_t), 1, fp) != 1) + else { - // Invalid Codestream - fprintf(stderr, CSTERROR); - fclose(fp); - return; + errno = 0; + argp_error(state, "The specified codeblock size (%ld) " + "is out of the supported range.\n", buff); + break; } - - endian_conversion(&Ls, 4); - fseek(fp, Ls - 4, SEEK_CUR); - - break; } - case EOH: + if (i == 1) { - if(fread(&Lh, sizeof(uint16_t), 1, fp) != 1) + arguments->cblkSize[1] = + arguments->cblkSize[2] = + arguments->cblkSize[3] = arguments->cblkSize[0]; + } + 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 deliminator 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) { - // Invalid Codestream - fprintf(stderr, CSTERROR); - fclose(fp); - return; + arguments->rate[i] = (double) compRatio; + } + else + { + errno = 0; + argp_error(state, "The specified compression ratio (%f) is " + "out of the supported range.\n", compRatio); } - - endian_conversion(&Lh, 2); - fseek(fp, Lh - 2, SEEK_CUR); - - status |= CODESTREAM_READ; - break; } - } - index++; - } - /*--------------------------------------------------------*\ - ! Determine the size of the main header present in the bwc ! - ! codestream and allocate the data structure, packed code- ! - ! stream sub-structure and its memory block. ! - \*--------------------------------------------------------*/ - Ld = ftell(fp); - fseek(fp, 0L, SEEK_SET); - - data = calloc(1, sizeof(bwc_data)); - if(data == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - fclose(fp); - return; - } - - data->codestream.data = calloc(1, sizeof(bwc_stream)); - if(data->codestream.data == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - bwc_free_data(data); - fclose(fp); - return; - } - - data->codestream.data->memory = calloc(Ld, sizeof(uchar)); - if(data->codestream.data->memory == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - bwc_free_data(data); - fclose(fp); - return; - } - - /*--------------------------------------------------------*\ - ! Read the main header from the packed codestream of the ! - ! user specified bcw file and set up the data structure. ! - \*--------------------------------------------------------*/ - if(fread(data->codestream.data->memory, sizeof(uchar), Ld, fp) != Ld) - { - // invalid read - fprintf(stderr, RDERROR); - bwc_free_data(data); - fclose(fp); - return; - } - - data->codestream.data->access = data->codestream.data->memory; - data->codestream.data->size = Ld; - data->codestream.data->position = 0; - - /*--------------------------------------------------------*\ - ! Initialize the bitstream, parse the main header and set ! - ! up the field structure for the current dataset. ! - \*--------------------------------------------------------*/ - field = bwc_create_decompression(data, 0); - if(field == NULL) - { - bwc_free_data(data); - fclose(fp); - return; - } - control = &field->control; - info = field->info; - - /*--------------------------------------------------------*\ - ! Write the help message to the standard output. ! - \*--------------------------------------------------------*/ - printf("/================================================================================\\\n"\ - "| |\n"\ - "| .:-------------: .:-------------: |\n"\ - "| .+++++++++++++++= :+++++++++++++++- |\n"\ - "| :+++. -++= -++= |\n"\ - "| :+++. -++= -++= |\n"\ - "| -++++++++++++++= -++= -++= |\n"\ - "| .=++---------=++= -++= -++= |\n"\ - "| :+++ :++= -++= -++= |\n"\ - "| .+++=--------=+++---=+++---=+++------------: |\n"\ - "| -=++++++++++++++++++++++++++++++++++++++++- |\n"\ - "| |\n"\ - "|------------------------------ General Information -----------------------------|\n"\ - "| |\n"); - - /*--------------------------------------------------------*\ - ! Print the original file size and format. ! - \*--------------------------------------------------------*/ - data_points = (uint64)info->nX * info->nY * info->nZ * - info->nTS * info->nPar; - buff = get_size(data_points * 8); - - printf("| Original size: %42s |\n"\ - "| Original file format: %42s |\n"\ - "|%80s|\n", buff, info->f_ext, " "); - - free(buff); - - /*--------------------------------------------------------*\ - ! Print the file size and compression ratio. ! - \*--------------------------------------------------------*/ - fseek(fp, 0L, SEEK_END); - Ld = ftell(fp); - buff = get_size(Ld); - fclose(fp); - - printf("| Size on Disk: %42s |\n"\ - "| Comp. Ratio: %42.2f |\n"\ - "|%80s|\n", buff, ((double)data_points * 8.0f/Ld), " "); - - free(buff); - - /*--------------------------------------------------------*\ - ! Print the number of datapoints. ! - \*--------------------------------------------------------*/ - buff = get_digit_sep(data_points); - printf("| Number of Datapoints: %42s |\n"\ - "|%80s|\n", buff, " "); - free(buff); - - buff = get_digit_sep(info->nX); - printf("| -1st Dim.: %42s |\n", buff); - free(buff); - - buff = get_digit_sep(info->nY); - printf("| -2nd Dim.: %42s |\n", buff); - free(buff); - - buff = get_digit_sep(info->nZ); - printf("| -3nd Dim.: %42s |\n", buff); - free(buff); - - buff = get_digit_sep(info->nTS); - printf("| -Time Steps: %42s |\n"\ - "| -No. Params: %42d |\n"\ - "|%80s|\n", buff, info->nPar, " "); - free(buff); - - /*--------------------------------------------------------*\ - ! Print the numerical Datapoints. ! - \*--------------------------------------------------------*/ - printf("|----------------------------- Numerical Parameters -----------------------------|\n"\ - "| |\n"); - - for(p = 0; p < info->nPar; ++p) - { - param_info = &field->tile[0].parameter[p].info; - - minVal = param_info->parameter_min; - maxVal = param_info->parameter_max; - - for(t = 0; t <= control->nTiles; ++t) - { - minVal = MIN(minVal, param_info->parameter_min); - maxVal = MIN(maxVal, param_info->parameter_max); + arguments->optSet |= CMPRT; + break; } - buff = param_info->name + strlen(param_info->name) - 1; - while(buff > param_info->name && isspace((unsigned char)*buff)) buff--; - buff[1] = '\0'; - - if(p != 0) + /* Ingest decomposition level. */ + case 'd': { - printf("| ........................................................................ |\n" - "|%80s|\n"," "); - } - - printf("| Name: %55s |\n"\ - "| Minimum value: %55.2e |\n"\ - "| Maximum value: %55.2e |\n", param_info->name, - minVal, - maxVal); - } - printf("|%80s|\n"," "); - /*--------------------------------------------------------*\ - ! Print the quality layers. ! - \*--------------------------------------------------------*/ - printf("|-------------------------------- Quality Layers --------------------------------|\n"\ - "| |\n"); - - for(l = 0; l < control->nLayers; ++l) - { - buff = get_size(data_points * control->bitrate[l]); - - printf("| |\n"\ - "| Quality Layer Nr. %d: %40.2f Bpd |\n"\ - "| %44s |\n", l + 1, control->bitrate[l], buff); - free(buff); - } - - printf("| |\n"\ - "\\--------------------------------------------------------------------------------/\n"); - - /*--------------------------------------------------------*\ - ! Free the field structure. ! - \*--------------------------------------------------------*/ - bwc_kill_compression(field); - bwc_free_data(data); -} - -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function opens a bwc file, checks it for its validity and loads its con- ! -! tent into a properly set up bwc_data structure. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! filename char* - Name of the bwc file that is ! -! to be opened and read. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! bwc_data* - Structure containing a code- ! -! stream/numerical dataset. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! 17.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static bwc_data* -read_bwc(char *const filename) -{ - /*-----------------------*\ - ! DEFINE INT VARIABLES: ! - \*-----------------------*/ - uint64_t Lfield; - uint16_t root; - - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_data *file; - - /*-----------------------*\ - ! DEFINE FILE POINTER: ! - \*-----------------------*/ - FILE *fp; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(filename); - - /*--------------------------------------------------------*\ - ! Open the specified file for reading and, if succesful, ! - ! determine the size of the codestream. If the file could ! - ! not be opened, print an error message to stderr and exit.! - \*--------------------------------------------------------*/ - fp = fopen(filename, "rb"); - if(fp != NULL) - { - root = ftell(fp); - fseek(fp, 0L, SEEK_END); - Lfield = ftell(fp) - root; - fseek(fp, root, SEEK_SET); - } - else - { - // error opening file - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: Could not open or read %-25s|\n"\ - "o##########################################################o\n", filename); - return NULL; - } - - /*--------------------------------------------------------*\ - ! Allocate the data and packed codestream structure as ! - ! well as the memory block that will hold the codestream. ! - \*--------------------------------------------------------*/ - file = calloc(1, sizeof(bwc_data)); - if(file == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - fclose(fp); - return NULL; - } - - file->codestream.data = calloc(1, sizeof(bwc_stream)); - if(file->codestream.data == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - bwc_free_data(file); - fclose(fp); - return NULL; - } - - file->codestream.data->memory = calloc(Lfield, sizeof(uchar)); - if(file->codestream.data->memory == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - bwc_free_data(file); - fclose(fp); - return NULL; - } - - /*--------------------------------------------------------*\ - ! Read the compressed bitstream from the file and, if suc- ! - ! essfull, properly set up the packed codestream and re- ! - ! turn the bwc_data structre to the function caller. ! - \*--------------------------------------------------------*/ - if(fread(file->codestream.data->memory, sizeof(uchar), Lfield, fp) != Lfield) - { - // invalid read - fprintf(stderr, RDERROR); - bwc_free_data(file); - fclose(fp); - return NULL; - } - - file->codestream.data->access = file->codestream.data->memory; - file->codestream.data->size = Lfield; - file->codestream.data->position = 0; - - fclose(fp); - return file; -} - -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function opens a bwc file, checks it for its validity and writes the code- ! -! stream, provided by the function caller, to the file. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! filename char* - Name of the bwc file that is ! -! to be created. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! unsigned char - Returns an unsigned char for ! -! error handling. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 20.06.2018 Patrick Vogler B87D120 V 0.1.0 function created ! -! 17.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static uchar -write_bwc(bwc_data *const data, - char *const filename) -{ - /*-----------------------*\ - ! DEFINE FILE POINTER: ! - \*-----------------------*/ - FILE *fp; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(data); - assert(filename); - - /*--------------------------------------------------------*\ - ! Open the specified file for writing If the file could ! - ! not be opened, print an error message to stderr and exit.! - \*--------------------------------------------------------*/ - fp = fopen(filename, "wb"); - if(fp == NULL) - { - // error opening file - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: Could not open %-33s|\n"\ - "o##########################################################o\n", filename); - return EXIT_FAILURE; - } - - /*--------------------------------------------------------*\ - ! Write the compressed codestream to file and, if success- ! - ! ful, close the file ptr and return to the fun. caller. ! - \*--------------------------------------------------------*/ - if(fwrite(data->codestream.data->memory, sizeof(uchar), data->codestream.data->size, fp) != - data->codestream.data->size) - { - // error opening file - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: Could not write to %-29s|\n"\ - "o##########################################################o\n", filename); - fclose(fp); - return EXIT_FAILURE; - } - - fclose(fp); - return EXIT_SUCCESS; -} - -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function is a wrapper that is used to invoke the appropriate read func- ! -! tion according to the file extension of the user supplied filename. The data- ! -! set is stored in the bwc_data structure and passed onto the function caller. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! args util_arg_node* - Arguments/options linked list ! -! for the bwc command-line tool. ! -! ! -! str char* - Long-/short-name of a bwc com- ! -! mand-line argument or option. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! bwc_data* - Structure containing a code- ! -! stream/numerical dataset. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 14.05.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! 03.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static bwc_data* -read_file(bwc_cmdl_arg_node *const args, - char* name) -{ - /*-----------------------*\ - ! DEFINE CHAR VARIABLES: ! - \*-----------------------*/ - char *str; - - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_cmdl_arg_node *temp; - bwc_data *file; - struct stat buf; - - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(args); - assert(name); - - /*--------------------------------------------------------*\ - ! Retrieve the file argument from the linked list and con- ! - ! firm that only one file has been specified and that it ! - ! is a regular file. ! - \*--------------------------------------------------------*/ - temp = retrieve_arg(args, name); - if((temp == NULL) || - (temp->lit_opt == NULL) || - (temp->lit_opt[0] == NULL)) - { - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: File |\n"\ - "| |\n"\ - "| No File has been specified. |\n"\ - "| |\n"\ - "o##########################################################o\n"); - return NULL; - } - - if(temp->count > 1) - { - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: File |\n"\ - "| |\n"\ - "| More than one file has been specified. |\n"\ - "| |\n"\ - "o##########################################################o\n"); - return NULL; - } - - stat(temp->lit_opt[0], &buf); - if(!S_ISREG(buf.st_mode)) - { - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: file |\n"\ - "| |\n"\ - "| The specified input is not a regular file. |\n"\ - "| |\n"\ - "o##########################################################o\n"); - return NULL; - } - - /*--------------------------------------------------------*\ - ! Extract the file extension from the input string and use ! - ! it to invoke the appropriate read function. ! - \*--------------------------------------------------------*/ - str = strrchr(temp->lit_opt[0], '.'); - switch(hash(str)) - { - case 0x000000017C4DC25C: - { - file = read_eas3(temp->lit_opt[0]); - if(file == NULL) + if (arguments->optSet & DCLVL) { - return NULL; + argp_error(state, "The compression ratio can only be defined once.\n"); } - return file; - } - - case 0x000000017C4DAF1D: - { - file = read_bwc(temp->lit_opt[0]); - if(file == NULL) + if (verify_opt(arg, ',', false) == EXIT_FAILURE) { - return NULL; + argp_error(state, "Invalid deliminator in the decomposition" + " level option.\n"); } - return file; + 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': + { + 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': + { + 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': + { + 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': + { + 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; + } + + /* Ingest Q number format range. */ + case 'm': + { + 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': + { + arguments->erresilience = true; + break; + } + + /* Ingest tile size. */ + case 't': + { + 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 deliminator 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': + { + 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 deliminator 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; + } + + /* Check if the user supplied options fit the supported * + * use case. */ + case ARGP_KEY_END: + { + 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); + break; + } + + /* Return error if key is unknown. */ default: - { - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: File |\n"\ - "| |\n"\ - "| The format of the specified file is currently |\n"\ - "| not supported. |\n"\ - "| |\n"\ - "o##########################################################o\n"); - return NULL; - } + return ARGP_ERR_UNKNOWN; } + return EXIT_SUCCESS; } -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function is a wrapper that is used to invoke the appropriate write func- ! -! tion according to the file extension supplied by the user or codestream. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! args util_arg_node* - Arguments/options linked list ! -! for the bwc command-line tool. ! -! ! -! str char* - Long-/short-name of a bwc com- ! -! mand-line argument or option. ! -! ! -! data bwc_data* - Structure containing a code- ! -! stream/numerical dataset. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! unsigned char - Returns an unsigned char for ! -! error handling. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 14.05.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! 17.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static uchar -write_file(bwc_cmdl_arg_node *const args, - bwc_data *const data, - char* name) +void +printheaderIO(char const *input, char const *output, char const *reference) { /*-----------------------*\ - ! DEFINE STRUCTS: ! + ! DEFINE CHAR VARIABLES: ! \*-----------------------*/ - uint64_t ext_hash; - uint16_t new_len; + 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 STRUCTS: ! + ! DEFINE INT VARIABLES: ! \*-----------------------*/ - bwc_cmdl_arg_node *temp; + uint8_t i; /*-----------------------*\ ! DEFINE CHAR VARIABLES: ! \*-----------------------*/ - char *str; + char cli_buffer[1024] = {0}; + char cli_verbose[4096] = {0}; - /*-----------------------*\ - ! DEFINE ASSERTIONS: ! - \*-----------------------*/ - assert(data); - assert(args); - assert(name); + strcat(cli_verbose, "\n"); + strcat(cli_verbose, "----------------- Compression Parameters -----------------\n"); + strcat(cli_verbose, "\n"); - /*--------------------------------------------------------*\ - ! Retrieve the file argument from the linked list and con- ! - ! firm that only one file has been specified. ! - \*--------------------------------------------------------*/ - temp = retrieve_arg(args, name); - if((temp == NULL) || - (temp->lit_opt == NULL) || - (temp->lit_opt[0] == NULL)) + 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) { - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: File |\n"\ - "| |\n"\ - "| No File has been specified. |\n"\ - "| |\n"\ - "o##########################################################o\n"); - return EXIT_FAILURE; + sprintf(cli_buffer, " Error Resilience: %27s\n", "true"); } - - if(temp->count > 1) - { - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: File |\n"\ - "| |\n"\ - "| More than one file has been specified. |\n"\ - "| |\n"\ - "o##########################################################o\n"); - return EXIT_FAILURE; - } - - /*--------------------------------------------------------*\ - ! If the output is a packed codestream, replace the user ! - ! supplied with the propper '.bwc' file extension to en- ! - ! sure uniformity. ! - \*--------------------------------------------------------*/ - if((retrieve_arg(args, "compress") != NULL) && (data->codestream.data != NULL)) - { - /*--------------------------------------------------------*\ - ! Extract the filename in the output argument, remove its ! - ! file extension and calculate the new string length with ! - ! the '.bwc' extension. ! - \*--------------------------------------------------------*/ - str = strrchr(temp->lit_opt[0], '.'); - str[1] = '\0'; - - new_len = (strlen(temp->lit_opt[0]) + 4) * sizeof(char); - - /*--------------------------------------------------------*\ - ! Resize the filename string in the output argument and ! - ! ammend the new file extension. ! - \*--------------------------------------------------------*/ - str = calloc(new_len, sizeof(char)); - if(str == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return EXIT_FAILURE; - } - sprintf(str, "%s%s", temp->lit_opt[0],"bwc"); - - /*--------------------------------------------------------*\ - ! Write the codestream to the filesystem. ! - \*--------------------------------------------------------*/ - if(write_bwc(data, str) == EXIT_FAILURE) - { - free(str); - return EXIT_FAILURE; - } - } - /*--------------------------------------------------------*\ - ! If the output is a numerical dataset, generate the ap- ! - ! propriate filename and write the information to file. ! - \*--------------------------------------------------------*/ - else if((retrieve_arg(args, "decompress") != NULL) && ((data->field.d != NULL) || - (data->field.f != NULL))) - { - /*--------------------------------------------------------*\ - ! If no output file has been specified, assemble the file- ! - ! name using the input name and file extension assoc. with ! - ! the codestream. Generate the ext. hash accordingly. ! - \*--------------------------------------------------------*/ - if(strcmp(name, "decompress") == 0) - { - ext_hash = hash(data->info.f_ext); - str = strrchr(temp->lit_opt[0], '.'); - str[0] = '\0'; - - new_len = (strlen(temp->lit_opt[0]) + - strlen(data->info.f_ext) + 7) * sizeof(char); - - str = calloc(new_len, sizeof(char)); - if(str == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return EXIT_FAILURE; - } - sprintf(str, "%s%s%s", temp->lit_opt[0], "_d.", data->info.f_ext); - } - /*--------------------------------------------------------*\ - ! If an output file has been specified, extract the file ! - ! extension, evaluate the corresponding hash and check ! - ! that the codestream supports the file format. ! - \*--------------------------------------------------------*/ - else - { - ext_hash = hash(strrchr(temp->lit_opt[0], '.') + 1); - if(ext_hash != hash(data->info.f_ext)) - { - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: Incompatible File Format |\n"\ - "| |\n"\ - "| The format of the specified file is incom- |\n"\ - "| patible with the information stored in the |\n"\ - "| codestream. |\n"\ - "| |\n"\ - "o##########################################################o\n"); - return EXIT_FAILURE; - } - - str = calloc(strlen(temp->lit_opt[0]) + 1, sizeof(char)); - if(str == NULL) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return EXIT_FAILURE; - } - strcpy(str, temp->lit_opt[0]); - } - - /*--------------------------------------------------------*\ - ! Use the extension hash to invoke the appropriate write ! - ! function. ! - \*--------------------------------------------------------*/ - switch (ext_hash) - { - case 0X0000000000B87A592: - { - if(write_eas3(data, str) == EXIT_FAILURE) - { - free(str); - return EXIT_FAILURE; - } - break; - } - - default: - { - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: File |\n"\ - "| |\n"\ - "| The format of the specified file is currently |\n"\ - "| not supported. |\n"\ - "| |\n"\ - "o##########################################################o\n"); - free(str); - return EXIT_FAILURE; - } - } - } - /*--------------------------------------------------------*\ - ! If no apporprite in- or output argument has been speci- ! - ! fied return an error handle to the function caller. ! - \*--------------------------------------------------------*/ else { - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: Data |\n"\ - "| |\n"\ - "| Output can not be generated because no valid |\n"\ - "| data has been specified. |\n"\ - "| |\n"\ - "o##########################################################o\n"); - return EXIT_FAILURE; + 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); } - free(str); - return EXIT_SUCCESS; + memset(cli_buffer, '0', sizeof(char) * 1024); + strcat(cli_verbose, "\n==============================================================\n"); + printf("%s", cli_verbose); } -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! | | ! -! This function calculates the Peak-Signal-to-Noise-Ratio of a compressed file ! -! in relation to the original reference file. The mean square error and peak ! -! signal to noise ratio are written to the standard output. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! args util_arg_node* - Arguments/options linked list ! -! for the bwc command-line tool. ! -! ! -! name char* - Long-/short-name of a bwc com- ! -! mand-line argument or option. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! unsigned char - Returns an unsigned char for ! -! error handling. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 12.09.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! 17.05.2021 Patrick Vogler B87E7E4 V 0.1.0 clean up ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -static uchar -output_analysis(bwc_cmdl_arg_node *const args) +static unsigned char +output_analysis(eas3_data *const ref_data, eas3_data *const org_data) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -2508,56 +1208,37 @@ output_analysis(bwc_cmdl_arg_node *const args) /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - bwc_data *file, *ref; + eas3_param_names *param_name; - bwc_cmd_opts_ll *param; + dOrig = org_data->field.d; + dRef = ref_data->field.d; - /*--------------------------------------------------------*\ - ! Load the input and reference files into the appropriate ! - ! file structures. ! - \*--------------------------------------------------------*/ - file = read_file(args, "input"); - if(file == NULL) + 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) { - return EXIT_FAILURE; - } - - ref = read_file(args, "reference"); - if(ref == NULL) - { - bwc_free_data(file); - return EXIT_FAILURE; - } - - dOrig = file->field.d; - dRef = ref->field.d; - - fOrig = file->field.f; - fRef = ref->field.f; - - if(file->info.nX == ref->info.nX && - file->info.nY == ref->info.nY && - file->info.nZ == ref->info.nZ && - file->info.nTS == ref->info.nTS && - file->info.nPar == ref->info.nPar) - { - size = (uint64_t)ref->info.nX * ref->info.nY * - ref->info.nZ * ref->info.nTS; + 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->info.parameter) + if(ref_data->param_names) { - param = ref->info.parameter->root; + param_name = ref_data->param_names->root; p = 0; - while(param != NULL) + while(param_name != NULL) { minVal = 1.7976931348623157e+308; maxVal = -1.7976931348623157e+308; - if(param->precision == 8) + if(ref_data->params.accuracy == 2) { for(i = 0; i < size; ++i) { @@ -2569,7 +1250,7 @@ output_analysis(bwc_cmdl_arg_node *const args) MSE += sum * sum; } } - else if(param->precision == 4) + else if(ref_data->params.accuracy == 1) { for(i = 0; i < size; ++i) { @@ -2582,562 +1263,502 @@ output_analysis(bwc_cmdl_arg_node *const args) } } peakVal = MAX(peakVal, maxVal - minVal); - param = param -> next; + param_name = param_name->next; p++; } } - MSE /= (double)size * ref->info.nPar; + MSE /= (double)size * ref_data->params.npar; PSNR = 20 * log10(peakVal/(2 * sqrt(MSE))); printf("==============================================================\n"); - printf(" Mean Square Error: %*.2f\n", 22, MSE); + printf(" Mean Square Error: %*.2e\n", 22, MSE); printf(" Peak Signal-to-Noise Ratio: %*.2f\n", 22, PSNR); printf("==============================================================\n"); } - /*--------------------------------------------------------*\ - ! Load the input and reference files into the appropriate ! - ! file structures. ! - \*--------------------------------------------------------*/ - bwc_free_data(file); - bwc_free_data(ref); return EXIT_SUCCESS; } -/**********************************************************************************************************************\ -|| ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || -|| |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || -|| | |__| |__] |___ | |___ | |__| | \| |___ | | |__| | \| ___] || -|| || -\**********************************************************************************************************************/ -/*--------------------------------------------------------------------------------------------------------------------*\ -! ! -! DESCRIPTION: ! -! ------------ ! -! This function provides a command-line interface for the BigWhoop compression ! -! library. ! -! ! -! PARAMETERS: ! -! ----------- ! -! Variable Type Description ! -! -------- ---- ----------- ! -! argc int - Number of strings pointed to ! -! by argv. ! -! ! -! argv char** - Array of arguments. ! -! ! -! RETURN VALUE: ! -! ------------- ! -! Type Description ! -! ---- ----------- ! -! int - Return value signaling a normal ! -! or abnormal process exit. ! -! ! -! DEVELOPMENT HISTORY: ! -! -------------------- ! -! ! -! Date Author Change Id Release Description ! -! ---- ------ --------- ------- ----------- ! -! 17.04.2019 Patrick Vogler B87D120 V 0.1.0 function created ! -! 15.05.2021 Patrick Vogler B880CA2 V 0.1.0 Clean up. ! -! ! -\*--------------------------------------------------------------------------------------------------------------------*/ -int -main(int argc, - char *argv[]) +/*================================================================================================*/ +/** + * @details Initialize the argp struct. used to parse the command line arguments + */ +/*================================================================================================*/ +static struct argp argp = {options, parse_opt, 0, doc, 0, 0, 0}; + +/*================================================================================================*/ +/** + * @details This function provides the command-line interface for the BigWhoop compression + * library. + * + * @param[in] argc Number of strings pointed to by argv + * @param[in] argv Array of arguments + * + * @retval -1 Error + * @retval 0 OK + */ +/*================================================================================================*/ +int main(int argc, char *argv[]) { + /*-----------------------*\ + ! DEFINE BOOL VARIABLES: ! + \*-----------------------*/ + bool delim = false; + /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ - uint64_t i; - uint8_t error_handle; + uint64_t size = 0; + uint64_t root, Lfield; + uint8_t i; + uint8_t error_handle = EXIT_SUCCESS; + + /*-----------------------*\ + ! DEFINE REAL VARIABLES: ! + \*-----------------------*/ + double rtype, exp; /*-----------------------*\ ! DEFINE CHAR VARIABLES: ! \*-----------------------*/ - char buff[200]; - char rate[10]; + char rate[200] = {0}; + + char *cli_output = NULL; + char *buffer = NULL; + + unsigned char *input = NULL; + unsigned char *output = NULL; + + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp = NULL; + + /*-----------------------*\ + ! DEFINE DER. VARIABLES: ! + \*-----------------------*/ + bwc_precision precision; + bwc_header *header; + bwc_stream *stream = NULL; + bwc_codec *coder = NULL; /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - bwc_field *field = NULL; - bwc_data *file = NULL; + eas3_data *data = NULL; + eas3_data *ref_data = NULL; + cli_arguments arguments = {0}; - bwc_gl_ctrl *control; - - //bwc_dwt_filter filter[4]; - bwc_cmdl_arg_node *args, *temp; - - /*--------------------------------------------------------*\ - ! Initialize the field and args structures for proper er- ! - ! ror handling, as well as the error handle itself. ! - \*--------------------------------------------------------*/ - field = NULL; - args = NULL; - - error_handle = EXIT_SUCCESS; - - /*--------------------------------------------------------*\ - ! Assemble the arg. linked list using the command-line ar- ! - ! guments passed by the function caller. ! - \*--------------------------------------------------------*/ - args = parse_arguments(argc, argv); - if(args == NULL) + /* 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; - print_help(); goto OUT; } - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - if(retrieve_arg(args, "compress") != NULL) + /* 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) { - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - if(retrieve_arg(args, "input")) - file = read_file(args, "input"); - else - file = read_file(args, "compress"); + /* 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.bwc", (int)(strlen(arguments.out) - strlen(buffer)), arguments.out); - if(file == NULL) + if (arguments.verbose == true) + { + 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; } - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - /*--------------------------------------------------------*\ - ! Save frequently used variables/structures to temporary ! - ! variables to make the code more readable. ! - \*--------------------------------------------------------*/ - field = bwc_initialize_field(file); - if(field == NULL) + /* Evaluate the input and output buffer size and initial- * + * size the BigWhoop data and coder structs. */ + size = data->params.ndim1 * data->params.ndim2 * + data->params.ndim3 * data->params.nts * + data->params.npar; + + if (data->params.accuracy == 1) { - error_handle = EXIT_FAILURE; - goto OUT; + precision = bwc_precision_single; + input = (unsigned char*)data->field.f; + output = calloc(size, sizeof(float)); } - control = &field->control; - - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - temp = retrieve_arg(args, "q_format_range"); - if((temp != NULL) && (temp->count == 1)) + else if (data->params.accuracy == 2) { - bwc_set_qm(field, (uint8_t)temp->num_opt[0]); + precision = bwc_precision_double; + input = (unsigned char*)data->field.d; + output = calloc(size, sizeof(double)); } - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - // temp = retrieve_arg(args, "wavelet_kernels"); - // if((temp != NULL) && (temp->count == 4) && (temp->dim != 0x00)) - // { - // for(i = 0; i < temp->count; ++i) - // { - // switch(hash(temp->lit_opt[i])) - // { - // case 0x000000000B87CF64: - // { - // filter[i] = bwc_dwt_9_7; - // break; - // } - // case 0x00000652AB15772A: - // { - // filter[i] = bwc_dwt_5_3; - // break; - // } - // case 0x000000017C858EFF: - // { - // filter[i] = bwc_dwt_5_3; - // break; - // } - // default: - // { - // filter[i] = bwc_dwt_9_7; - // break; - // } - // } - // } - // bwc_set_kernels(field, filter[0], filter[1], - // filter[2], filter[3]); - // } + 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_set_aux(stream, (char*)data->aux.ptr, data->aux.len); - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - temp = retrieve_arg(args, "decomposition_levels"); - if((temp != NULL) && (temp->count == 4) && (temp->dim != 0x00)) + if ((arguments.optSet & TILES) != 0) { - bwc_set_decomp(field, (uint8_t)temp->num_opt[0], (uint8_t)temp->num_opt[1], - (uint8_t)temp->num_opt[2], (uint8_t)temp->num_opt[3]); + bwc_set_tiles(coder, arguments.tileSize[0], + arguments.tileSize[1], + arguments.tileSize[2], + arguments.tileSize[3], bwc_tile_sizeof); + } - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - temp = retrieve_arg(args, "tile_size"); - if((temp != NULL) && (temp->count == 4) && (temp->dim != 0x00)) + // TODO: Implement the kernel setter as a global function + // and define the proper verbose output layout. + /*if ((arguments.optSet & DWTKL) != 0) { - bwc_set_tiles(field, (uint64_t)temp->num_opt[0], (uint64_t)temp->num_opt[1], - (uint64_t)temp->num_opt[2], (uint64_t)temp->num_opt[3], bwc_tile_sizeof); + bwc_set_kernels(coder, arguments.dwtKernel[0], + arguments.dwtKernel[1], + arguments.dwtKernel[2], + arguments.dwtKernel[3]); + }*/ + + if ((arguments.optSet & DCLVL) != 0) + { + bwc_set_decomp(coder, arguments.decompLevel[0], + arguments.decompLevel[1], + arguments.decompLevel[2], + arguments.decompLevel[3]); } - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - temp = retrieve_arg(args, "precinct_size"); - if((temp != NULL) && (temp->count == 4) && (temp->dim != 0x00)) + if ((arguments.optSet & PRECS) != 0) { - bwc_set_precincts(field, (uint8_t)temp->num_opt[0], (uint8_t)temp->num_opt[1], - (uint8_t)temp->num_opt[2], (uint8_t)temp->num_opt[3]); + bwc_set_precincts(coder, arguments.precSize[0], + arguments.precSize[1], + arguments.precSize[2], + arguments.precSize[3]); } - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - temp = retrieve_arg(args, "codeblock_size"); - if((temp != NULL) && (temp->count == 4) && (temp->dim != 0x00)) + if ((arguments.optSet & CBLKS) != 0) { - bwc_set_codeblocks(field, (uint8_t)temp->num_opt[0], (uint8_t)temp->num_opt[1], - (uint8_t)temp->num_opt[2], (uint8_t)temp->num_opt[3]); + bwc_set_codeblocks(coder, arguments.cblkSize[0], + arguments.cblkSize[1], + arguments.cblkSize[2], + arguments.cblkSize[3]); } - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - // temp = retrieve_arg(args, "quantisation_style"); - // if((temp != NULL) && (temp->count == 1)) - // { - // if(strcmp(temp->lit_opt[0], "NONE")) - // bwc_set_quant_style(field, bwc_qt_none); - // else - // bwc_set_quant_style(field, bwc_qt_derived); - // } - - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - // temp = retrieve_arg(args, "quantisation_step_size"); - // if((temp != NULL) && (temp->count == 1)) - // { - // bwc_set_quant_step_size(field, temp->num_opt[0]); - // } - - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - memset(buff, 0, 200 * sizeof(char)); - - temp = retrieve_arg(args, "bitrate"); - if((temp != NULL) && (temp->count > 0)) + if ((arguments.optSet & QFRMT) != 0) { - for(i = 0; i < temp->count && strlen(buff) < 192; ++i) - { - sprintf(rate, "%05.3f,", temp->num_opt[i]); - strcat(buff, rate); - } - buff[strlen(buff) - 1] = '0'; + bwc_set_qm(coder, arguments.Qm); } - temp = retrieve_arg(args, "compression_ratio"); - if((temp != NULL) && (temp->count == 1)) + if (arguments.erresilience == true) { - sprintf(buff, "%05.3f", ((double)PREC_BIT + 1.0f)/temp->num_opt[0]); + bwc_set_error_resilience(coder); + } - if(strlen(buff) == 0) + /* Initialize the rate control string according to the * + * specified bit rate/compression ratio. */ + if ((arguments.optSet & BITRT) != 0) { - sprintf(buff, "-"); + rtype = 1.0; + exp = 1.0; } - - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - #if defined (_OPENMP) - temp = retrieve_arg(args, "number_of_threads"); - if((temp != NULL) && (temp->count == 1)) - { - omp_set_num_threads((uint8_t)temp->num_opt[0]); - } - #endif - - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - if(retrieve_arg(args, "error_resilience")) + else if ((arguments.optSet & CMPRT) != 0) { - bwc_set_error_resilience(field); - } - - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - if(bwc_create_compression(field, buff)) - { - error_handle = EXIT_FAILURE; - goto OUT; - } - - if(bwc_compress(field, file)) - { - error_handle = EXIT_FAILURE; - goto OUT; - } - - - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - if(retrieve_arg(args, "output")) - { - if(write_file(args, file, "output")) - { - error_handle = EXIT_FAILURE; - goto OUT; - } + rtype = 64.0; + exp = -1.0; } else { - if(write_file(args, file, "compress")) - { - error_handle = EXIT_FAILURE; - goto OUT; - } + rtype = 1.0; + exp = 1.0; + arguments.rate[0] = 64; } - temp = retrieve_arg(args, "verbose"); - if(temp != NULL) + + for(i = 0; i < 10 && strlen(rate) < 192; ++i) { - /*--------------------------------------------------------*\ - ! Calculate the original field size, compression ratio and ! - ! bits per datapoint and print the miscellaneous compres- ! - ! sion information to the standard output. ! - \*--------------------------------------------------------*/ - if((temp->count == 1) && (temp->num_opt[0] > 1) && (control->CSsgc != 0)) + if (arguments.rate[i] > 0) { - printf("==============================================================\n"); - printf(" \n"\ - " .:-------------: .:-------------: \n"\ - " .+++++++++++++++= :+++++++++++++++- \n"\ - " :+++. -++= -++= \n"\ - " :+++. -++= -++= \n"\ - " -++++++++++++++= -++= -++= \n"\ - " .=++---------=++= -++= -++= \n"\ - " :+++ :++= -++= -++= \n"\ - " .+++=--------=+++---=+++---=+++------------: \n"\ - " -=++++++++++++++++++++++++++++++++++++++++- \n"\ - " \n"); - printf("----------------- Compression Parameters -----------------\n\n"); - if((control->CSsgc &0x200) != 0) - { - printf(" Number of Tiles: %27ld\n", control->nTiles); - printf(" - Samples in 1.D: %27ld\n", control->tileSizeX); - printf(" - Samples in 2.D: %27ld\n", control->tileSizeY); - printf(" - Samples in 3.D: %27ld\n", control->tileSizeZ); - printf(" - Timesteps: %27ld\n", control->tileSizeTS); - printf(" ..........................................................\n"); - printf("\n"); - } - - if((control->CSsgc &0xE0) != 0) - { - printf(" 1.D | 2.D | 3.D | TS\n"); - if((control->CSsgc &0x20) != 0) - { - printf(" Decomposition Levels: %2d | %2d | %2d | %2d\n", control->decompX - , control->decompY - , control->decompZ - , control->decompTS); - } - if((control->CSsgc &0x40) != 0) - { - printf(" Precincts [log2]: %2d | %2d | %2d | %2d\n", control->precSizeX - , control->precSizeY - , control->precSizeZ - , control->precSizeTS); - - } - if((control->CSsgc &0x80) != 0) - { - printf(" Codeblocks [log2]: %2d | %2d | %2d | %2d\n", control->cbX - , control->cbY - , control->cbZ - , control->cbTS); - } - printf(" ..........................................................\n"); - printf("\n"); - } - - if((control->CSsgc &0x101) != 0) - { - if((control->CSsgc &0x100) != 0) - printf(" Q Number Format: %27d\n", control->Qm); - if((control->CSsgc &0x1) != 0) - printf(" Error Resilience: %27s\n", ((control->error_resilience > 0) ? "True" : "False")); - - printf(" ..........................................................\n"); - printf("\n"); - } - - for(i = 0; i < control->nLayers; ++i) - { - printf(" Quality Layer Nr. %2ld: %23.2f bpd\n", i + 1, control->bitrate[i]/8.0f); - } - - printf("\n"); - printf("---------------- Compression Performance -----------------\n\n"); - } - else - { - printf("==============================================================\n"); + sprintf(rate + strlen(rate), "%05.3f,", pow(arguments.rate[i]/rtype, exp)); } } - } - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - else if(retrieve_arg(args, "decompress") != NULL) - { - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - if(retrieve_arg(args, "input")) - file = read_file(args, "input"); - else - file = read_file(args, "decompress"); + rate[strlen(rate) - 1] = '0'; - if(file == NULL) + if (bwc_create_compression(coder, stream, rate) == EXIT_FAILURE) { error_handle = EXIT_FAILURE; goto OUT; } - if(file->codestream.data == NULL) + if(arguments.verbose == true) + { + printctrl(&coder->control); + } + + size = bwc_compress(coder, stream); + + /* Write the codestream to the speicifed file. */ + fp = fopen(cli_output, "wb"); + if (fp == NULL) { - fprintf(stderr, "o##########################################################o\n"\ - "| ERROR: File |\n"\ - "| |\n"\ - "| Input file does not contain a packed code- |\n"\ - "| stream. |\n"\ - "| |\n"\ - "o##########################################################o\n"); - error_handle = EXIT_FAILURE; + printf(FOUERROR); goto OUT; } - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - temp = retrieve_arg(args, "layer"); - if((temp != NULL) && (temp->count == 1)) - field = bwc_create_decompression(file, (uint8_t)temp->num_opt[0]); - else - field = bwc_create_decompression(file, 0); - - if(field == NULL) - { - error_handle = EXIT_FAILURE; - goto OUT; - } - - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - #if defined (_OPENMP) - temp = retrieve_arg(args, "number_of_threads"); - if((temp != NULL) && (temp->count == 1)) - { - omp_set_num_threads((uint8_t)temp->num_opt[0]); - } - #endif - - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - if(bwc_decompress(field, file)) - { - error_handle = EXIT_FAILURE; - goto OUT; - } - - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - if(retrieve_arg(args, "output")) - { - if(write_file(args, file, "output")) - { - error_handle = EXIT_FAILURE; - goto OUT; - } - } - else - { - if(write_file(args, file, "decompress")) - { - error_handle = EXIT_FAILURE; - goto OUT; - } - } - } - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - else if(retrieve_arg(args, "info") != NULL) - { - if(retrieve_arg(args, "input")) - output_info(args, "input"); - else - output_info(args, "info"); - } - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ - else if(retrieve_arg(args, "analysis") != NULL) - { - if(output_analysis(args) == EXIT_FAILURE) + if (fwrite(stream->out, sizeof(unsigned char), size, fp) != size) { error_handle = EXIT_FAILURE; + printf(WRTERROR); goto OUT; } } - /*--------------------------------------------------------*\ - ! ! - \*--------------------------------------------------------*/ + else if (arguments.mode == cli_dcp) + { + /* 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) + { + printheaderIO(arguments.in, cli_output, arguments.ref); + } + + 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(unsigned char)); + if (fread(input, sizeof(unsigned char), 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); + + printctrl(&header->control); + + /* 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); + write_eas3(data, cli_output); + + goto OUT; + } + 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) + { + 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(unsigned char)); + if (fread(input, sizeof(unsigned char), 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); + + if(arguments.verbose == true) + { + printctrl(&header->control); + } + + /* 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) + { + printheaderIO(arguments.in, cli_output, arguments.ref); + + 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(unsigned char)); + if (fread(input, sizeof(unsigned char), Lfield, fp) != Lfield) + { + error_handle = EXIT_FAILURE; + printf(RDERROR); + goto OUT; + } + + /* Retrieve header information. */ + 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); + + printctrl(&header->control); + } else { - print_help(); - goto OUT; + return EXIT_FAILURE; } OUT: - if(field != NULL) - { - bwc_kill_compression(field); - } + if (coder != NULL) + bwc_free_codec(coder); - if(file != NULL) - { - bwc_free_data(file); - } + if (data != NULL) + eas3_free_data(data); - if(args != NULL) - { - bwc_kill_arg(args); - } + if (ref_data != NULL) + eas3_free_data(ref_data); - fclose(stdin); - fclose(stdout); - fclose(stderr); + if (stream !=NULL) + free(stream); + + if (output != NULL) + free(output); + + if (cli_output != NULL) + free(cli_output); + + if (fp != NULL) + fclose(fp); return error_handle; -} \ No newline at end of file +}