From ad3a1ad06149c2cb39e9ea2f1ba3df8879bd6cf0 Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Fri, 28 Jun 2024 16:37:19 +0200 Subject: [PATCH] Symmetrize API for compression and decompression to follow - allocate codec - initialize stream (using input data/codestream and output buffer from user) - create (de-)compression - run (de-)compression --- include/library/private/codestream.h | 7 +- include/library/private/constants.h | 6 + include/library/private/libbwc.h | 37 ++-- include/library/private/types.h | 11 +- src/library/bitstream.c | 5 + src/library/codestream.c | 133 ++++++------ src/library/libbwc.c | 294 +++++++++++++++------------ 7 files changed, 275 insertions(+), 218 deletions(-) diff --git a/include/library/private/codestream.h b/include/library/private/codestream.h index 7b2c1f5..6165760 100755 --- a/include/library/private/codestream.h +++ b/include/library/private/codestream.h @@ -97,9 +97,10 @@ uchar codestream_write_com (bwc_span *const header, bwc_span *const com); //==========|==========================|======================|======|======|===================== - bwc_span* assemble_codestream (bwc_codec *const field, - bwc_stream *const data); + bwc_span* assemble_codestream (bwc_codec *const codec, + bwc_stream *const stream); //==========|==========================|======================|======|======|===================== - bwc_codec* parse_codestream (bwc_stream *const data, + 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 35bd7ef..1251b4e 100755 --- a/include/library/private/constants.h +++ b/include/library/private/constants.h @@ -118,4 +118,10 @@ 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/libbwc.h b/include/library/private/libbwc.h index fdeb409..7becb04 100755 --- a/include/library/private/libbwc.h +++ b/include/library/private/libbwc.h @@ -64,29 +64,41 @@ || || \************************************************************************************************/ //==========|==========================|======================|======|=======|==================== - bwc_stream* bwc_initialize_data (void *const data, - bwc_precision const prec); + bwc_stream* bwc_init_stream (void *const inpbuf, + void *const outbuf, + bwc_mode const mode); //==========|==========================|======================|======|=======|==================== - uchar bwc_set_com (bwc_stream *const data, + uchar bwc_set_com (bwc_stream *const stream, char const *const com, uint16 const size); //==========|==========================|======================|======|=======|==================== - uchar bwc_set_aux (bwc_stream *const data, + uchar bwc_set_aux (bwc_stream *const stream, char const *const aux, uint32 const size); //==========|==========================|======================|======|=======|==================== + // TODO: remove void bwc_free_data (bwc_stream *const data); //==========|==========================|======================|======|=======|==================== - uchar create_field (bwc_codec *const field); + uchar create_field (bwc_codec *const codec); //==========|==========================|======================|======|=======|==================== - void bwc_kill_compression (bwc_codec *const field); - //==========|==========================|======================|======|=======|==================== - bwc_codec* bwc_initialize_field (bwc_precision const prec, + bwc_codec* configure_codec (bwc_codec *const codec, uint64 const nX, uint64 const nY, uint64 const nZ, uint16 const nTS, - uint8 const nPar); + uint8 const nPar, + bwc_precision const prec); + //==========|==========================|======================|======|=======|==================== + bwc_codec* bwc_alloc_coder (uint64 const nX, + uint64 const nY, + uint64 const nZ, + uint16 const nTS, + uint8 const nPar, + bwc_precision const prec); + //==========|==========================|======================|======|=======|==================== + bwc_codec* bwc_alloc_decoder (); + //==========|==========================|======================|======|=======|==================== + void bwc_free_codec (bwc_codec *const codec); //==========|==========================|======================|======|=======|==================== void bwc_set_error_resilience (bwc_codec *const field); //==========|==========================|======================|======|=======|==================== @@ -140,9 +152,10 @@ uchar bwc_compress (bwc_codec *const field, bwc_stream *const data); //==========|==========================|======================|======|=======|==================== - bwc_codec* bwc_create_decompression (bwc_stream *const data, + uchar bwc_create_decompression (bwc_codec *const codec, + bwc_stream *const stream, uint8 const layer); //==========|==========================|======================|======|=======|==================== - uchar bwc_decompress (bwc_codec *const field, - bwc_stream *const data); + uchar bwc_decompress (bwc_codec *const codec, + bwc_stream *const stream); #endif \ No newline at end of file diff --git a/include/library/private/types.h b/include/library/private/types.h index fcacd32..3dc8bf3 100755 --- a/include/library/private/types.h +++ b/include/library/private/types.h @@ -177,11 +177,10 @@ bwc_span *com; // Comment codestream block. }codestream; - struct field - { - double *d; // Double precision numerical data-set. - float *f; // Single precision numerical data-set. - }field; + void *inp; // User managed buffer for input + void *out; // User managed buffer for output + + bwc_mode mode; // Flag to signal (de-)compression } bwc_stream; /*----------------------------------------------------------------------------------------------*\ @@ -679,5 +678,7 @@ bwc_gl_ctrl control; // Global control structure bwc_tile *tile; // Structure defining bwc tile. + + bwc_mode mode; // Flag to signal (de-)compression } bwc_codec; #endif \ No newline at end of file diff --git a/src/library/bitstream.c b/src/library/bitstream.c index fee6777..c36cde0 100755 --- a/src/library/bitstream.c +++ b/src/library/bitstream.c @@ -168,6 +168,8 @@ init_stream(uchar* memory, uint32 size, char instr) return NULL; } + // TODO: Here is a problem. Memory might be allocated here or coming from outside. + // Violates RAII. Can lead to problem in terminate_stream. /*--------------------------------------------------------*\ ! Evaluate if a valid memory handle has been passed by the ! ! function caller. ! @@ -903,6 +905,9 @@ terminate_stream(bitstream *stream, bwc_span *const packed_stream) \*-----------------------*/ assert(stream); + // TODO: this seems dangerous because the bitstream is generated from provided (non-owning) pointer or allocated (owning). + // If the former is the case a user might get reallocations on his/her pointer. + // This risk is eminent now as bwc_stream data.out is now a user provided buffer pointer. if(packed_stream) { if(stream->error) diff --git a/src/library/codestream.c b/src/library/codestream.c index 24955ad..309e6ff 100755 --- a/src/library/codestream.c +++ b/src/library/codestream.c @@ -603,7 +603,7 @@ assemble_tile(bwc_codec *const field, bwc_tile *const tile, bitstream *const str ! ! \*----------------------------------------------------------------------------------------------------------*/ bwc_codec* -parse_main_header(bwc_stream *const data, bitstream *const stream) +parse_main_header(bwc_codec *const codec, bwc_stream *const data, bitstream *const stream) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -631,16 +631,23 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - bwc_codec *field; bwc_gl_ctrl *control; bwc_gl_inf *info; /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ + assert(codec); assert(data); assert(stream); + /*--------------------------------------------------------*\ + ! Save the global control and info structure to temporary ! + ! variables to make the code more readable. ! + \*--------------------------------------------------------*/ + info = &codec->info; + control = &codec->control; + status = CODESTREAM_OK; index = 0; @@ -690,23 +697,22 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) break; } - nX = get_symbol(stream, 8); - nY = get_symbol(stream, 8); - nZ = get_symbol(stream, 8); - nTS = (uint16)get_symbol(stream, 2); - nPar = (uint8)get_symbol(stream, 1); - data_prec = (bwc_precision)get_symbol(stream, 1); + nX = get_symbol(stream, 8); + nY = get_symbol(stream, 8); + nZ = get_symbol(stream, 8); + nTS = (uint16)get_symbol(stream, 2); + nPar = (uint8)get_symbol(stream, 1); + data_prec = (bwc_precision)get_symbol(stream, 1); + codec_prec = (bwc_precision)get_symbol(stream, 1); - field = bwc_initialize_field(data_prec, nX, nY, nZ, nTS, nPar); - if(!field) + info->codec_prec = codec_prec; + + configure_codec(codec, nX, nY, nZ, nTS, nPar, data_prec); + if(!codec) { status |= CODESTREAM_ERROR; break; } - info = &field->info; - control = &field->control; - - info->codec_prec = codec_prec = (bwc_precision)get_symbol(stream, 1); control->codestreamSize = stream->Lmax; @@ -720,7 +726,7 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -731,7 +737,7 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -742,14 +748,14 @@ parse_main_header(bwc_stream *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); @@ -765,41 +771,41 @@ parse_main_header(bwc_stream *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); @@ -808,7 +814,7 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) buffTS = get_symbol(stream, 2); if(CSsgc & (0x01 << 9)) { - bwc_set_tiles(field, buffX, buffY, buffZ, (uint16)buffTS, bwc_tile_sizeof); + bwc_set_tiles(codec, buffX, buffY, buffZ, (uint16)buffTS, bwc_tile_sizeof); } control->nLayers = get_symbol(stream, 1); @@ -817,7 +823,7 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) { // memory allocation error fprintf(stderr, MEMERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status|= CODESTREAM_ERROR; break; } @@ -828,10 +834,10 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) control->bitrate[l] = *(float *)&bitrate; } - create_field(field); - if(!field) + create_field(codec); + if(!codec) { - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -846,7 +852,7 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -856,7 +862,7 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -866,7 +872,7 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) { // memory allocation error fprintf(stderr, MEMERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -884,7 +890,7 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -894,7 +900,7 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -904,7 +910,7 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) { // memory allocation error fprintf(stderr, MEMERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -924,7 +930,7 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -934,7 +940,7 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -953,10 +959,10 @@ parse_main_header(bwc_stream *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; } } } @@ -974,20 +980,20 @@ parse_main_header(bwc_stream *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; @@ -999,7 +1005,7 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -1009,7 +1015,7 @@ parse_main_header(bwc_stream *const data, bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(codec); status |= CODESTREAM_ERROR; break; } @@ -1272,7 +1278,7 @@ parse_body(bwc_codec *const field, bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(field); status |= CODESTREAM_ERROR; break; } @@ -1282,7 +1288,7 @@ parse_body(bwc_codec *const field, bitstream *const stream) { // Invalid Codestream fprintf(stderr, CSERROR); - bwc_kill_compression(field); + bwc_free_codec(field); status |= CODESTREAM_ERROR; break; } @@ -1343,12 +1349,13 @@ assemble_codestream(bwc_codec *const field, bwc_stream *const data) bwc_gl_ctrl *control; bwc_tile *tile; bitstream *stream; - bwc_span *packed_stream; + bwc_span *packed_stream; /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ assert(field); + assert(data); /*--------------------------------------------------------*\ ! Save the global control and info structure to temporary ! @@ -1388,7 +1395,7 @@ assemble_codestream(bwc_codec *const field, bwc_stream *const data) ! Initialize the final codestream and emit the header ! ! bytes. ! \*--------------------------------------------------------*/ - stream = init_stream(NULL, control->codestreamSize, 'c'); + stream = init_stream(data->out, control->codestreamSize, 'c'); codestream_write_header(stream, field, data); /*--------------------------------------------------------*\ @@ -1460,31 +1467,31 @@ assemble_codestream(bwc_codec *const field, bwc_stream *const data) ! ! \*----------------------------------------------------------------------------------------------------------*/ bwc_codec* -parse_codestream(bwc_stream *const data, uint8 const layer) +parse_codestream(bwc_codec *const codec, bwc_stream *const data, uint8 const layer) { /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - bwc_codec *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_stream(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; } @@ -1493,36 +1500,36 @@ parse_codestream(bwc_stream *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; + return codec; } \ No newline at end of file diff --git a/src/library/libbwc.c b/src/library/libbwc.c index 83d7c9b..5f7a6a1 100755 --- a/src/library/libbwc.c +++ b/src/library/libbwc.c @@ -819,7 +819,7 @@ fill_buffer(bwc_codec *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_d = data->field.d; + tmp_d = (double *)data->inp; /*--------------------------------------------------------*\ ! Walk through the tile parameter working buffer. ! @@ -867,7 +867,7 @@ fill_buffer(bwc_codec *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. ! @@ -1047,7 +1047,7 @@ flush_buffer(bwc_codec *const field, bwc_tile *const tile, bwc_parameter *const ! 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. ! @@ -1089,7 +1089,7 @@ flush_buffer(bwc_codec *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. ! @@ -1375,6 +1375,45 @@ denormalize_param(bwc_codec *const field, bwc_parameter *const parameter) } } +/*----------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function allocates an instance of type bwc_codec and stores the codec precision. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! bwc_codec* Defines the (de)compression data structure. ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +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; +} + /************************************************************************************************************\ || ___ _ _ ___ _ _ ____ ____ _ _ _ _ ____ ___ _ ____ _ _ ____ || || |__] | | |__] | | | |___ | | |\ | | | | | | |\ | [__ || @@ -1382,7 +1421,7 @@ denormalize_param(bwc_codec *const field, bwc_parameter *const parameter) || || \************************************************************************************************************/ /*----------------------------------------------------------------------------------------------------------*\ -! FUNCTION NAME: bwc_codec *bwc_initialize_data(...) ! +! FUNCTION NAME: bwc_codec *bwc_init_stream(...) ! ! -------------- ! ! ! ! DESCRIPTION: ! @@ -1417,31 +1456,26 @@ denormalize_param(bwc_codec *const field, bwc_parameter *const parameter) ! ! \*----------------------------------------------------------------------------------------------------------*/ bwc_stream* -bwc_initialize_data(void *const data, bwc_precision const prec) +bwc_init_stream(void *const inpbuf, void *const outbuf, bwc_mode const mode) { /*-----------------------*\ ! DEFINE STRUCTS: ! \*-----------------------*/ - bwc_stream *file; + bwc_stream *stream; - file = calloc(1, sizeof(bwc_stream)); - if(!file) + stream = calloc(1, sizeof(bwc_stream)); + if(!stream) { // memory allocation error fprintf(stderr, MEMERROR); return NULL; } - if (prec == bwc_precision_double) - { - file->field.d = (double *)data; - } - else if (prec == bwc_precision_single) - { - file->field.f = (float *)data; - } + stream->inp = inpbuf; + stream->out = outbuf; + stream->mode = mode; - return file; + return stream; } /*----------------------------------------------------------------------------------------------------------*\ @@ -1576,8 +1610,6 @@ bwc_free_data(bwc_stream* data) free(data->codestream.data); free(data->codestream.aux); free(data->codestream.com); - free(data->field.d); - free(data->field.f); free(data); } } @@ -2020,7 +2052,7 @@ create_field(bwc_codec *const field) ! ! \*----------------------------------------------------------------------------------------------------------*/ void -bwc_kill_compression(bwc_codec *const field) +bwc_free_codec(bwc_codec *const codec) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -2036,109 +2068,94 @@ bwc_kill_compression(bwc_codec *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_codec *bwc_initialize_field(bwc_stream *const data) ! -! -------------- ! ! ! ! DESCRIPTION: ! ! ------------ ! -! This function initializes the bwc_codec structure with all necessary standard parameters ! -! to (de)compress a floating point array with nX * nY * nZ grid points, nTS timesteps and ! +! This function configures the bwc_codec structure with all necessary standard parameters ! +! to 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_codec* 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_codec* -bwc_initialize_field(bwc_precision const prec, uint64 const nX, uint64 const nY, uint64 const nZ, uint16 const nTS, uint8 const nPar) +configure_codec(bwc_codec *const codec, uint64 const nX, uint64 const nY, uint64 const nZ, + uint16 const nTS, uint8 const nPar, bwc_precision const prec) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! @@ -2157,24 +2174,12 @@ bwc_initialize_field(bwc_precision const prec, uint64 const nX, uint64 const nY, bwc_gl_ctrl *control; bwc_gl_inf *info; - /*--------------------------------------------------------*\ - ! Allocate the root compression data structure. ! - \*--------------------------------------------------------*/ - bwc_codec *field = calloc(1, sizeof(bwc_codec)); - 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; + control = &codec->control; + info = &codec->info; info->nX = nX; info->nY = nY; @@ -2183,15 +2188,6 @@ bwc_initialize_field(bwc_precision const prec, uint64 const nX, uint64 const nY, info->nPar = nPar; info->data_prec = prec; - /*--------------------------------------------------------*\ - ! Save the codec precision in the info structure. ! - \*--------------------------------------------------------*/ -#if PREC_BYTE == 8 - info->codec_prec = bwc_precision_double; -#elif PREC_BYTE == 4 - info->codec_prec = bwc_precision_single; -#endif - /*--------------------------------------------------------*\ ! Set all tile sizes to their maximum allowable value. The ! ! value for the number of tiles is set to 1. ! @@ -2277,7 +2273,7 @@ bwc_initialize_field(bwc_precision const prec, uint64 const nX, uint64 const nY, \*--------------------------------------------------------*/ if(initialize_gain_lut()) { - bwc_kill_compression(field); + bwc_free_codec(codec); return NULL; } @@ -2287,7 +2283,7 @@ bwc_initialize_field(bwc_precision const prec, uint64 const nX, uint64 const nY, ! 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))); @@ -2311,7 +2307,63 @@ bwc_initialize_field(bwc_precision const prec, uint64 const nX, uint64 const nY, } } - return field; + return codec; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function initializes the bwc_codec structure with all necessary standard parameters ! +! to (de)compress a floating point array with nX * nY * nZ grid points, nTS timesteps and ! +! nPar parameters. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! bwc_codec* Defines the (de)compression data structure. ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +bwc_codec* +bwc_alloc_coder(uint64 const nX, uint64 const nY, uint64 const nZ, uint16 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; +} + +/*----------------------------------------------------------------------------------------------------------*\ +! ! +! DESCRIPTION: ! +! ------------ ! +! This function initializes the bwc_codec structure with all necessary standard parameters ! +! to (de)compress a floating point array with nX * nY * nZ grid points, nTS timesteps and ! +! nPar parameters. ! +! ! +! RETURN VALUE: ! +! ------------- ! +! Type Description ! +! ---- ----------- ! +! bwc_codec* Defines the (de)compression data structure. ! +! ! +\*----------------------------------------------------------------------------------------------------------*/ +bwc_codec* +bwc_alloc_decoder() +{ + /*--------------------------------------------------------*\ + ! Allocate the root compression data structure. ! + \*--------------------------------------------------------*/ + bwc_codec *codec = alloc_codec(); + codec->mode = decomp; + + return codec; } /*----------------------------------------------------------------------------------------------------------*\ @@ -2818,7 +2870,7 @@ bwc_set_decomp(bwc_codec *const field, uint8 decompX, uint8 decompY, uint8 decom \*--------------------------------------------------------*/ if(initialize_gain_lut()) { - bwc_kill_compression(field); + bwc_free_codec(field); return; } @@ -3436,6 +3488,7 @@ bwc_create_compression(bwc_codec *codec, bwc_stream *stream, char *rate_control) ! DEFINE ASSERTIONS: ! \*-----------------------*/ assert(codec); + assert(stream); /*--------------------------------------------------------*\ ! Save the global control structure to a temporary varia- ! @@ -3929,33 +3982,29 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data) ! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! ! ! \*----------------------------------------------------------------------------------------------------------*/ -bwc_codec * -bwc_create_decompression(bwc_stream *const data, uint8 layer) +uchar +bwc_create_decompression(bwc_codec *const decoder, bwc_stream *const stream, uint8 layer) { - /*-----------------------*\ - ! DEFINE STRUCTS: ! - \*-----------------------*/ - bwc_codec *field; - /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ - assert(data); + assert(decoder); + assert(stream); /*--------------------------------------------------------*\ - ! Parse the codestream and setup the field codestream. ! + ! Parse the stream and setup the decoder. ! \*--------------------------------------------------------*/ - field = parse_codestream(data, layer); - if(!field) + parse_codestream(decoder, stream, layer); + if(!decoder) { - return NULL; + return 1; } /*--------------------------------------------------------*\ - ! If successful, return the field structure to the func- ! + ! If successful, return the decoder structure to the func- ! ! tion caller. ! \*--------------------------------------------------------*/ - return field; + return 0; } /*----------------------------------------------------------------------------------------------------------*\ @@ -4003,7 +4052,6 @@ bwc_decompress(bwc_codec *const field, bwc_stream *const data) ! DEFINE INT VARIABLES: ! \*-----------------------*/ uint64 buff_size; - uint64 data_size; uint64 i; uint16 p; @@ -4055,30 +4103,6 @@ bwc_decompress(bwc_codec *const field, bwc_stream *const data) control = &field->control; info = &field->info; - data_size = info->nX * info->nY * info->nZ * info->nTS * info->nPar; - if(info->data_prec == bwc_precision_double) - { - data->field.d = calloc(data_size, sizeof(double)); - data->field.f = calloc(0, sizeof(float)); - if(!data->field.d) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return 1; - } - } - else if (info->data_prec == bwc_precision_single) - { - data->field.d = calloc(0, sizeof(double)); - data->field.f = calloc(data_size, sizeof(float)); - if(!data->field.f) - { - // memory allocation error - fprintf(stderr, MEMERROR); - return 1; - } - } - /*--------------------------------------------------------*\ ! Evaluate the working buffer size and allocate it accord- ! ! ingly. !