From 0673dafb64edd3f9563c2e87bf77dff856fd56a5 Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Mon, 1 Jul 2024 11:01:44 +0200 Subject: [PATCH 1/3] rename init_stream(...) -> init_bitstream(...). init_bitstream without allocation. emit_symbol and emit_chunck without reallocation. --- include/library/private/bitstream.h | 2 +- src/library/bitstream.c | 142 +++++++--------------------- src/library/codestream.c | 6 +- src/library/tier2.c | 12 ++- 4 files changed, 49 insertions(+), 113 deletions(-) diff --git a/include/library/private/bitstream.h b/include/library/private/bitstream.h index 3ec7a78..42f6763 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); //==========|==========================|======================|======|======|===================== diff --git a/src/library/bitstream.c b/src/library/bitstream.c index c36cde0..b023bdd 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,39 +167,11 @@ 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. ! - \*--------------------------------------------------------*/ - 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); @@ -249,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: ! \*-----------------------*/ @@ -261,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. ! @@ -372,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 ! diff --git a/src/library/codestream.c b/src/library/codestream.c index 309e6ff..a8afd0e 100755 --- a/src/library/codestream.c +++ b/src/library/codestream.c @@ -1395,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(data->out, control->codestreamSize, 'c'); + stream = init_bitstream(data->out, control->codestreamSize, 'c'); codestream_write_header(stream, field, data); /*--------------------------------------------------------*\ @@ -1414,7 +1414,7 @@ assemble_codestream(bwc_codec *const field, bwc_stream *const data) assemble_tile(field, tile, stream); } - emit_symbol(stream, EOC, 2); + emit_symbol(&(*stream), EOC, 2); packed_stream = calloc(1, sizeof(bwc_span)); if(!packed_stream) @@ -1484,7 +1484,7 @@ parse_codestream(bwc_codec *const codec, bwc_stream *const data, uint8 const lay ! Initialize a bitstream used to parse the packed code- ! ! stream. ! \*--------------------------------------------------------*/ - stream = init_stream(data->inp, 10, 'd'); + stream = init_bitstream(data->inp, 10, 'd'); /*--------------------------------------------------------*\ ! Parse the main header and set up the codec structure for ! diff --git a/src/library/tier2.c b/src/library/tier2.c index 5c3a08a..e784c8d 100755 --- a/src/library/tier2.c +++ b/src/library/tier2.c @@ -450,6 +450,7 @@ create_packet(bwc_codec *const field, bwc_tile *const tile, int16 *cp_contr; int16 delta_z; int8 m; + uchar *memory; /*-----------------------*\ ! DEFINE STRUCTS: ! @@ -482,7 +483,14 @@ create_packet(bwc_codec *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 @@ -1392,7 +1400,7 @@ parse_packet(bwc_codec *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 From 1c41147b73bf70ddff222d78b771346f34d0ce93 Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Tue, 2 Jul 2024 17:58:41 +0200 Subject: [PATCH 2/3] resolved terminate_stream into shrink_to_fit and transfer_to_span. transferal of stream to span not required in assemble_codestream anymore. assemble_codestream and bwc_compress return the size of the compressed data. user provided buffer is used. --- include/library/private/bitstream.h | 6 +- include/library/private/codestream.h | 2 +- include/library/private/libbwc.h | 2 +- src/library/bitstream.c | 94 ++++++++++++++-------------- src/library/codestream.c | 26 +++----- src/library/libbwc.c | 21 ++++--- src/library/tier2.c | 7 ++- 7 files changed, 76 insertions(+), 82 deletions(-) diff --git a/include/library/private/bitstream.h b/include/library/private/bitstream.h index 42f6763..1e8aacc 100755 --- a/include/library/private/bitstream.h +++ b/include/library/private/bitstream.h @@ -117,8 +117,10 @@ //==========|==========================|======================|======|======|===================== uchar get_bit (bitstream *const stream); //==========|==========================|======================|======|======|===================== - uchar terminate_stream (bitstream *stream, - bwc_span *const packed_stream); + uchar shrink_to_fit (bitstream *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 6165760..e7f54fc 100755 --- a/include/library/private/codestream.h +++ b/include/library/private/codestream.h @@ -97,7 +97,7 @@ uchar codestream_write_com (bwc_span *const header, bwc_span *const com); //==========|==========================|======================|======|======|===================== - bwc_span* assemble_codestream (bwc_codec *const codec, + size_t assemble_codestream (bwc_codec *const codec, bwc_stream *const stream); //==========|==========================|======================|======|======|===================== bwc_codec* parse_codestream (bwc_codec *const codec, diff --git a/include/library/private/libbwc.h b/include/library/private/libbwc.h index 7becb04..7c65f6d 100755 --- a/include/library/private/libbwc.h +++ b/include/library/private/libbwc.h @@ -149,7 +149,7 @@ bwc_stream *const data, char *const rate_control); //==========|==========================|======================|======|=======|==================== - uchar bwc_compress (bwc_codec *const field, + size_t bwc_compress (bwc_codec *const field, bwc_stream *const data); //==========|==========================|======================|======|=======|==================== uchar bwc_create_decompression (bwc_codec *const codec, diff --git a/src/library/bitstream.c b/src/library/bitstream.c index b023bdd..2780b65 100755 --- a/src/library/bitstream.c +++ b/src/library/bitstream.c @@ -798,74 +798,74 @@ 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_span *const packed_stream) +shrink_to_fit(bitstream *const stream) { /*-----------------------*\ ! DEFINE ASSERTIONS: ! \*-----------------------*/ 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) { - 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; - } - } + } + return 0; +} - packed_stream->memory = stream->memory; - packed_stream->access = stream->memory; - packed_stream->size = stream->L; - packed_stream->position = 0; - } - else +/*----------------------------------------------------------------------------------------------------------*\ +! 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) { - free(stream->memory); + return 1; } - - free(stream); + + span->memory = stream->memory; + span->access = stream->memory; + span->size = stream->L; + span->position = 0; + + stream->memory = NULL; + stream->L = 0; + return 0; } diff --git a/src/library/codestream.c b/src/library/codestream.c index a8afd0e..48255fa 100755 --- a/src/library/codestream.c +++ b/src/library/codestream.c @@ -1335,12 +1335,13 @@ parse_body(bwc_codec *const field, bitstream *const stream) ! 13.06.2019 Patrick Vogler B87D120 V 0.1.0 function created ! ! ! \*----------------------------------------------------------------------------------------------------------*/ -bwc_span* +size_t assemble_codestream(bwc_codec *const field, bwc_stream *const data) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ + size_t compressed_size; uint64 i; /*-----------------------*\ @@ -1349,7 +1350,6 @@ assemble_codestream(bwc_codec *const field, bwc_stream *const data) bwc_gl_ctrl *control; bwc_tile *tile; bitstream *stream; - bwc_span *packed_stream; /*-----------------------*\ ! DEFINE ASSERTIONS: ! @@ -1385,7 +1385,7 @@ assemble_codestream(bwc_codec *const field, bwc_stream *const data) \*--------------------------------------------------------*/ if(sequence_packets(field, tile)) { - return NULL; + return 0; } control->codestreamSize += tile->control.header_size + tile->control.body_size; @@ -1414,24 +1414,12 @@ assemble_codestream(bwc_codec *const field, bwc_stream *const data) assemble_tile(field, tile, stream); } - emit_symbol(&(*stream), EOC, 2); + emit_symbol(stream, EOC, 2); - packed_stream = calloc(1, sizeof(bwc_span)); - 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; } /*----------------------------------------------------------------------------------------------------------*\ diff --git a/src/library/libbwc.c b/src/library/libbwc.c index 5f7a6a1..239655c 100755 --- a/src/library/libbwc.c +++ b/src/library/libbwc.c @@ -3652,12 +3652,13 @@ bwc_create_compression(bwc_codec *codec, bwc_stream *stream, char *rate_control) ! 15.03.2018 Patrick Vogler B87D120 V 0.1.0 function created ! ! ! \*----------------------------------------------------------------------------------------------------------*/ -uchar +size_t bwc_compress(bwc_codec *const field, bwc_stream *const data) { /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ + size_t compressed_size = 0; uint64 buff_size = 0; uint64 i; uint16 p; @@ -3731,7 +3732,7 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data) { // memory allocation error fprintf(stderr, MEMERROR); - return 1; + return 0; } /*--------------------------------------------------------*\ @@ -3812,7 +3813,7 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data) if(forward_wavelet_transform(field, parameter)) { free(working_buffer); - return 1; + return 0; } #ifdef BWC_PROFILE #if defined (_OPENMP) @@ -3837,7 +3838,7 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data) if(t1_encode(field, tile, parameter)) { free(working_buffer); - return 1; + return 0; } #ifdef BWC_PROFILE #if defined (_OPENMP) @@ -3868,7 +3869,7 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data) if(t2_encode(field, tile)) { free(working_buffer); - return 1; + return 0; } #ifdef BWC_PROFILE #if defined (_OPENMP) @@ -3890,11 +3891,11 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data) start = (double)clock(); #endif #endif - data->codestream.data = assemble_codestream(field, data); - if(!data->codestream.data) + compressed_size = assemble_codestream(field, data); + if(compressed_size == 0) { free(working_buffer); - return 1; + return 0; } #ifdef BWC_PROFILE #if defined (_OPENMP) @@ -3922,7 +3923,7 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data) #endif nfs = (uint64)(info->nX * info->nY * info->nZ * info->nTS * info->nPar * info->data_prec); - css = (uint64)data->codestream.data->size; + css = (uint64)compressed_size; cpr = (double)nfs/css; @@ -3944,7 +3945,7 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data) /*--------------------------------------------------------*\ ! Return to the function caller. ! \*--------------------------------------------------------*/ - return 0; + return compressed_size; } /*----------------------------------------------------------------------------------------------------------*\ diff --git a/src/library/tier2.c b/src/library/tier2.c index e784c8d..c492162 100755 --- a/src/library/tier2.c +++ b/src/library/tier2.c @@ -652,7 +652,8 @@ create_packet(bwc_codec *const field, bwc_tile *const tile, } k = header->L; - terminate_stream(header, NULL); + free(header->memory); + free(header); return k; } /*--------------------------------------------------------*\ @@ -663,11 +664,13 @@ create_packet(bwc_codec *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; From 3242165d9097f39037bda0e29d67cea8aca59d2a Mon Sep 17 00:00:00 2001 From: Gregor Weiss Date: Tue, 2 Jul 2024 18:07:19 +0200 Subject: [PATCH 3/3] remove unused bwc_span bwc_stream.codestream.data --- include/library/private/types.h | 1 - src/library/libbwc.c | 5 ----- 2 files changed, 6 deletions(-) diff --git a/include/library/private/types.h b/include/library/private/types.h index 3dc8bf3..0320a8e 100755 --- a/include/library/private/types.h +++ b/include/library/private/types.h @@ -172,7 +172,6 @@ { struct codestream { - bwc_span *data; // Data codestream block. bwc_span *aux; // Auxiliary info. codestream block. bwc_span *com; // Comment codestream block. }codestream; diff --git a/src/library/libbwc.c b/src/library/libbwc.c index 239655c..bbbda4e 100755 --- a/src/library/libbwc.c +++ b/src/library/libbwc.c @@ -1595,10 +1595,6 @@ bwc_free_data(bwc_stream* data) { if(data) { - if(data->codestream.data) - { - release_packed_stream(data->codestream.data); - } if(data->codestream.aux) { release_packed_stream(data->codestream.aux); @@ -1607,7 +1603,6 @@ bwc_free_data(bwc_stream* data) { release_packed_stream(data->codestream.com); } - free(data->codestream.data); free(data->codestream.aux); free(data->codestream.com); free(data);