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
This commit is contained in:
Gregor Weiss 2024-06-28 16:37:19 +02:00
parent 008ccfa4a9
commit ad3a1ad061
Signed by: Gregor Weiss
GPG key ID: 61E170A8BBFE5756
7 changed files with 275 additions and 218 deletions

View file

@ -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

View file

@ -118,4 +118,10 @@
bwc_precision_single = 4,
bwc_precision_double = 8,
} bwc_precision;
typedef enum
{
comp,
decomp,
} bwc_mode;
#endif

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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;
}

View file

@ -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. !