Merge pull request 'Cleaned memory management for bitstream' (#41) from develop-gws into feat/api

This commit is contained in:
Patrick Vogler 2024-07-09 11:45:28 +02:00
commit bbc538d5e8
Signed by: Patrick Vogler
GPG key ID: 5536B08CE82E8509
8 changed files with 123 additions and 199 deletions

View file

@ -92,7 +92,7 @@
\************************************************************************************************/ \************************************************************************************************/
uint64 bytes_used (bitstream const *const stream); uint64 bytes_used (bitstream const *const stream);
//==========|==========================|======================|======|======|===================== //==========|==========================|======================|======|======|=====================
bitstream* init_stream (uchar *const memory, bitstream* init_bitstream (uchar *const memory,
uint32 const size, uint32 const size,
char const instr); char const instr);
//==========|==========================|======================|======|======|===================== //==========|==========================|======================|======|======|=====================
@ -117,8 +117,10 @@
//==========|==========================|======================|======|======|===================== //==========|==========================|======================|======|======|=====================
uchar get_bit (bitstream *const stream); uchar get_bit (bitstream *const stream);
//==========|==========================|======================|======|======|===================== //==========|==========================|======================|======|======|=====================
uchar terminate_stream (bitstream *stream, uchar shrink_to_fit (bitstream *const stream);
bwc_span *const packed_stream); //==========|==========================|======================|======|======|=====================
uchar transfer_to_span (bitstream *const stream,
bwc_span *const span);
//==========|==========================|======================|======|======|===================== //==========|==========================|======================|======|======|=====================
void release_packed_stream (bwc_span *const stream); void release_packed_stream (bwc_span *const stream);
#endif #endif

View file

@ -97,7 +97,7 @@
uchar codestream_write_com (bwc_span *const header, uchar codestream_write_com (bwc_span *const header,
bwc_span *const com); 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_stream *const stream);
//==========|==========================|======================|======|======|===================== //==========|==========================|======================|======|======|=====================
bwc_codec* parse_codestream (bwc_codec *const codec, bwc_codec* parse_codestream (bwc_codec *const codec,

View file

@ -149,7 +149,7 @@
bwc_stream *const data, bwc_stream *const data,
char *const rate_control); char *const rate_control);
//==========|==========================|======================|======|=======|==================== //==========|==========================|======================|======|=======|====================
uchar bwc_compress (bwc_codec *const field, size_t bwc_compress (bwc_codec *const field,
bwc_stream *const data); bwc_stream *const data);
//==========|==========================|======================|======|=======|==================== //==========|==========================|======================|======|=======|====================
uchar bwc_create_decompression (bwc_codec *const codec, uchar bwc_create_decompression (bwc_codec *const codec,

View file

@ -172,7 +172,6 @@
{ {
struct codestream struct codestream
{ {
bwc_span *data; // Data codestream block.
bwc_span *aux; // Auxiliary info. codestream block. bwc_span *aux; // Auxiliary info. codestream block.
bwc_span *com; // Comment codestream block. bwc_span *com; // Comment codestream block.
}codestream; }codestream;

View file

@ -107,8 +107,6 @@ bytes_used(bitstream const *const stream)
} }
/*----------------------------------------------------------------------------------------------------------*\ /*----------------------------------------------------------------------------------------------------------*\
! FUNCTION NAME: bitstream* bwc_init_stream(uchar* memory, uint32 size, char instr) !
! -------------- !
! ! ! !
! DESCRIPTION: ! ! DESCRIPTION: !
! ------------ ! ! ------------ !
@ -145,7 +143,7 @@ bytes_used(bitstream const *const stream)
! ! ! !
\*----------------------------------------------------------------------------------------------------------*/ \*----------------------------------------------------------------------------------------------------------*/
bitstream* bitstream*
init_stream(uchar* memory, uint32 size, char instr) init_bitstream(uchar* memory, uint32 size, char instr)
{ {
/*-----------------------*\ /*-----------------------*\
! DEFINE STRUCTS: ! ! DEFINE STRUCTS: !
@ -155,6 +153,7 @@ init_stream(uchar* memory, uint32 size, char instr)
/*-----------------------*\ /*-----------------------*\
! DEFINE ASSERTIONS: ! ! DEFINE ASSERTIONS: !
\*-----------------------*/ \*-----------------------*/
assert(memory);
assert(instr == 'c' || instr == 'd'); assert(instr == 'c' || instr == 'd');
/*--------------------------------------------------------*\ /*--------------------------------------------------------*\
@ -168,39 +167,11 @@ init_stream(uchar* memory, uint32 size, char instr)
return NULL; 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 ! ! Initialize the byte buffer counter, stream size and size !
! increment for the current stream. ! ! increment for the current stream. !
\*--------------------------------------------------------*/ \*--------------------------------------------------------*/
stream->memory = memory;
stream->t = (instr == 'c') ? 8 : 0; stream->t = (instr == 'c') ? 8 : 0;
stream->Lmax = size; stream->Lmax = size;
stream->size_incr = (uint64)(size / 2); stream->size_incr = (uint64)(size / 2);
@ -249,11 +220,6 @@ init_stream(uchar* memory, uint32 size, char instr)
void void
emit_chunck(bitstream *const stream, const uchar* chunck, const uint64 size) emit_chunck(bitstream *const stream, const uchar* chunck, const uint64 size)
{ {
/*-----------------------*\
! DEFINE INT VARIABLES: !
\*-----------------------*/
uint64 Lreq;
/*-----------------------*\ /*-----------------------*\
! DEFINE ASSERTIONS: ! ! DEFINE ASSERTIONS: !
\*-----------------------*/ \*-----------------------*/
@ -261,39 +227,16 @@ emit_chunck(bitstream *const stream, const uchar* chunck, const uint64 size)
assert(chunck); assert(chunck);
/*--------------------------------------------------------*\ /*--------------------------------------------------------*\
! Evaluate the memory block size if the current chunck of ! ! Check if an error was encountered in a previous writing !
! data is written to the stream. ! ! 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 the stream is not large enough, check if this is due !
! to an error encountered in a previous writing operation !
\*--------------------------------------------------------*/ \*--------------------------------------------------------*/
if(!stream->error) if(!stream->error)
{ {
/*--------------------------------------------------------*\ /*--------------------------------------------------------*\
! If the error flag is not set, increase the stream size ! ! Check if the enough memory has been allocated for the !
! until it is large enough to store the additional data ! ! stream to store the additional symbol. !
! chunck. !
\*--------------------------------------------------------*/ \*--------------------------------------------------------*/
while(Lreq > stream->Lmax) if((bytes_used(stream) + size) > 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 // memory allocation error
stream->error |= 1; stream->error |= 1;
@ -308,7 +251,6 @@ emit_chunck(bitstream *const stream, const uchar* chunck, const uint64 size)
\*--------------------------------------------------------*/ \*--------------------------------------------------------*/
return; return;
} }
}
/*--------------------------------------------------------*\ /*--------------------------------------------------------*\
! Copy the additional data to the stream memory block. ! ! Copy the additional data to the stream memory block. !
@ -372,29 +314,16 @@ emit_symbol(bitstream *const stream, const uint64 symbol, const uint8 size)
assert(stream); assert(stream);
/*--------------------------------------------------------*\ /*--------------------------------------------------------*\
! Check if the enough memory has been allocated for the ! ! Check if an error was encountered in a previous writing !
! stream to store the additional symbol. ! ! operation !
\*--------------------------------------------------------*/
if((bytes_used(stream) + size) > 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(!stream->error)
{ {
/*--------------------------------------------------------*\ /*--------------------------------------------------------*\
! If the error flag is not set, increment the stream size ! ! Check if the enough memory has been allocated for the !
! to store the additional symbol. ! ! stream to store the additional symbol. !
\*--------------------------------------------------------*/ \*--------------------------------------------------------*/
stream->Lmax += stream->size_incr; if((bytes_used(stream) + size) > stream->Lmax)
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 // memory allocation error
stream->error |= 1; stream->error |= 1;
@ -409,7 +338,6 @@ emit_symbol(bitstream *const stream, const uint64 symbol, const uint8 size)
\*--------------------------------------------------------*/ \*--------------------------------------------------------*/
return; return;
} }
}
/*--------------------------------------------------------*\ /*--------------------------------------------------------*\
! Copy the additional symbol to the stream memory block ! ! Copy the additional symbol to the stream memory block !
@ -870,51 +798,28 @@ flush_stream(bitstream *const stream)
} }
/*----------------------------------------------------------------------------------------------------------*\ /*----------------------------------------------------------------------------------------------------------*\
! FUNCTION NAME: void *test(void) !
! -------------- !
! !
! DESCRIPTION: ! ! DESCRIPTION: !
! ------------ ! ! ------------ !
! DESCRIPTION NEEDED ! ! Shrinks the bitstream memory to the actually filled range. !
! !
! PARAMETERS: !
! ----------- !
! Variable Type Description !
! -------- ---- ----------- !
! - - - !
! ! ! !
! RETURN VALUE: ! ! RETURN VALUE: !
! ------------- ! ! ------------- !
! Type Description ! ! Returns 0 if successfull and 1 if memory could not be resized. !
! ---- ----------- !
! - - !
! !
! DEVELOPMENT HISTORY: !
! -------------------- !
! !
! Date Author Change Id Release Description Of Change !
! ---- ------ --------- ------- --------------------- !
! - Patrick Vogler B87D120 V 0.1.0 function created !
! ! ! !
\*----------------------------------------------------------------------------------------------------------*/ \*----------------------------------------------------------------------------------------------------------*/
uchar uchar
terminate_stream(bitstream *stream, bwc_span *const packed_stream) shrink_to_fit(bitstream *const stream)
{ {
/*-----------------------*\ /*-----------------------*\
! DEFINE ASSERTIONS: ! ! DEFINE ASSERTIONS: !
\*-----------------------*/ \*-----------------------*/
assert(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) if(stream->error)
{ {
return 1; return 1;
} }
else if(stream->L != stream->Lmax) else if(stream->L > stream->Lmax)
{ {
stream->Lmax = stream->L; stream->Lmax = stream->L;
stream->memory = realloc(stream->memory, stream->Lmax); stream->memory = realloc(stream->memory, stream->Lmax);
@ -926,18 +831,41 @@ terminate_stream(bitstream *stream, bwc_span *const packed_stream)
return 1; 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)
{ {
free(stream->memory); /*-----------------------*\
! DEFINE ASSERTIONS: !
\*-----------------------*/
assert(stream);
assert(span);
if(stream->error)
{
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; return 0;
} }

View file

@ -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 ! ! 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) assemble_codestream(bwc_codec *const field, bwc_stream *const data)
{ {
/*-----------------------*\ /*-----------------------*\
! DEFINE INT VARIABLES: ! ! DEFINE INT VARIABLES: !
\*-----------------------*/ \*-----------------------*/
size_t compressed_size;
uint64 i; uint64 i;
/*-----------------------*\ /*-----------------------*\
@ -1349,7 +1350,6 @@ assemble_codestream(bwc_codec *const field, bwc_stream *const data)
bwc_gl_ctrl *control; bwc_gl_ctrl *control;
bwc_tile *tile; bwc_tile *tile;
bitstream *stream; bitstream *stream;
bwc_span *packed_stream;
/*-----------------------*\ /*-----------------------*\
! DEFINE ASSERTIONS: ! ! DEFINE ASSERTIONS: !
@ -1385,7 +1385,7 @@ assemble_codestream(bwc_codec *const field, bwc_stream *const data)
\*--------------------------------------------------------*/ \*--------------------------------------------------------*/
if(sequence_packets(field, tile)) if(sequence_packets(field, tile))
{ {
return NULL; return 0;
} }
control->codestreamSize += tile->control.header_size + control->codestreamSize += tile->control.header_size +
tile->control.body_size; tile->control.body_size;
@ -1395,7 +1395,7 @@ assemble_codestream(bwc_codec *const field, bwc_stream *const data)
! Initialize the final codestream and emit the header ! ! Initialize the final codestream and emit the header !
! bytes. ! ! bytes. !
\*--------------------------------------------------------*/ \*--------------------------------------------------------*/
stream = init_stream(data->out, control->codestreamSize, 'c'); stream = init_bitstream(data->out, control->codestreamSize, 'c');
codestream_write_header(stream, field, data); codestream_write_header(stream, field, data);
/*--------------------------------------------------------*\ /*--------------------------------------------------------*\
@ -1416,22 +1416,10 @@ assemble_codestream(bwc_codec *const field, bwc_stream *const data)
emit_symbol(stream, EOC, 2); emit_symbol(stream, EOC, 2);
packed_stream = calloc(1, sizeof(bwc_span)); compressed_size = stream->L;
if(!packed_stream) free(stream);
{
// memory allocation error
fprintf(stderr, MEMERROR);
return NULL;
}
if(terminate_stream(stream, packed_stream)) return compressed_size;
{
return NULL;
}
else
{
return packed_stream;
}
} }
/*----------------------------------------------------------------------------------------------------------*\ /*----------------------------------------------------------------------------------------------------------*\
@ -1484,7 +1472,7 @@ parse_codestream(bwc_codec *const codec, bwc_stream *const data, uint8 const lay
! Initialize a bitstream used to parse the packed code- ! ! Initialize a bitstream used to parse the packed code- !
! stream. ! ! 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 ! ! Parse the main header and set up the codec structure for !

View file

@ -1595,10 +1595,6 @@ bwc_free_data(bwc_stream* data)
{ {
if(data) if(data)
{ {
if(data->codestream.data)
{
release_packed_stream(data->codestream.data);
}
if(data->codestream.aux) if(data->codestream.aux)
{ {
release_packed_stream(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); release_packed_stream(data->codestream.com);
} }
free(data->codestream.data);
free(data->codestream.aux); free(data->codestream.aux);
free(data->codestream.com); free(data->codestream.com);
free(data); free(data);
@ -3652,12 +3647,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 ! ! 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) bwc_compress(bwc_codec *const field, bwc_stream *const data)
{ {
/*-----------------------*\ /*-----------------------*\
! DEFINE INT VARIABLES: ! ! DEFINE INT VARIABLES: !
\*-----------------------*/ \*-----------------------*/
size_t compressed_size = 0;
uint64 buff_size = 0; uint64 buff_size = 0;
uint64 i; uint64 i;
uint16 p; uint16 p;
@ -3731,7 +3727,7 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data)
{ {
// memory allocation error // memory allocation error
fprintf(stderr, MEMERROR); fprintf(stderr, MEMERROR);
return 1; return 0;
} }
/*--------------------------------------------------------*\ /*--------------------------------------------------------*\
@ -3812,7 +3808,7 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data)
if(forward_wavelet_transform(field, parameter)) if(forward_wavelet_transform(field, parameter))
{ {
free(working_buffer); free(working_buffer);
return 1; return 0;
} }
#ifdef BWC_PROFILE #ifdef BWC_PROFILE
#if defined (_OPENMP) #if defined (_OPENMP)
@ -3837,7 +3833,7 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data)
if(t1_encode(field, tile, parameter)) if(t1_encode(field, tile, parameter))
{ {
free(working_buffer); free(working_buffer);
return 1; return 0;
} }
#ifdef BWC_PROFILE #ifdef BWC_PROFILE
#if defined (_OPENMP) #if defined (_OPENMP)
@ -3868,7 +3864,7 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data)
if(t2_encode(field, tile)) if(t2_encode(field, tile))
{ {
free(working_buffer); free(working_buffer);
return 1; return 0;
} }
#ifdef BWC_PROFILE #ifdef BWC_PROFILE
#if defined (_OPENMP) #if defined (_OPENMP)
@ -3890,11 +3886,11 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data)
start = (double)clock(); start = (double)clock();
#endif #endif
#endif #endif
data->codestream.data = assemble_codestream(field, data); compressed_size = assemble_codestream(field, data);
if(!data->codestream.data) if(compressed_size == 0)
{ {
free(working_buffer); free(working_buffer);
return 1; return 0;
} }
#ifdef BWC_PROFILE #ifdef BWC_PROFILE
#if defined (_OPENMP) #if defined (_OPENMP)
@ -3922,7 +3918,7 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data)
#endif #endif
nfs = (uint64)(info->nX * info->nY * info->nZ * info->nTS * info->nPar * info->data_prec); 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; cpr = (double)nfs/css;
@ -3944,7 +3940,7 @@ bwc_compress(bwc_codec *const field, bwc_stream *const data)
/*--------------------------------------------------------*\ /*--------------------------------------------------------*\
! Return to the function caller. ! ! Return to the function caller. !
\*--------------------------------------------------------*/ \*--------------------------------------------------------*/
return 0; return compressed_size;
} }
/*----------------------------------------------------------------------------------------------------------*\ /*----------------------------------------------------------------------------------------------------------*\

View file

@ -450,6 +450,7 @@ create_packet(bwc_codec *const field, bwc_tile *const tile,
int16 *cp_contr; int16 *cp_contr;
int16 delta_z; int16 delta_z;
int8 m; int8 m;
uchar *memory;
/*-----------------------*\ /*-----------------------*\
! DEFINE STRUCTS: ! ! 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- ! ! Initialize the stream that is used to assemble the pack- !
! et header. ! ! 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) if(!header)
{ {
// memory allocation error // memory allocation error
@ -644,7 +652,8 @@ create_packet(bwc_codec *const field, bwc_tile *const tile,
} }
k = header->L; k = header->L;
terminate_stream(header, NULL); free(header->memory);
free(header);
return k; return k;
} }
/*--------------------------------------------------------*\ /*--------------------------------------------------------*\
@ -655,11 +664,13 @@ create_packet(bwc_codec *const field, bwc_tile *const tile,
\*--------------------------------------------------------*/ \*--------------------------------------------------------*/
else else
{ {
if(terminate_stream(header, &packet->header)) if(shrink_to_fit(header))
{ {
// memory allocation error // memory allocation error
return -1; return -1;
} }
transfer_to_span(header, &packet->header);
free(header);
packet->size = packet->body.size + packet->header.size; packet->size = packet->body.size + packet->header.size;
@ -1392,7 +1403,7 @@ parse_packet(bwc_codec *const field, bwc_tile *const tile,
! Initialize the stream that is used to parse the packet ! ! Initialize the stream that is used to parse the packet !
! codestream. ! ! codestream. !
\*--------------------------------------------------------*/ \*--------------------------------------------------------*/
header = init_stream(packet->header.memory, body_size, 'd'); header = init_bitstream(packet->header.memory, body_size, 'd');
if(!header) if(!header)
{ {
// memory allocation error // memory allocation error