Implemented the compression path with verbose output and support for all options available to the user.

This commit is contained in:
Patrick Vogler 2024-10-29 19:01:33 +01:00
parent 90645bcf1b
commit d979950626
Signed by: Patrick Vogler
GPG key ID: 5536B08CE82E8509

View file

@ -48,6 +48,8 @@
#include <argp.h> #include <argp.h>
#include <assert.h> #include <assert.h>
#include <inttypes.h> #include <inttypes.h>
#include <math.h>
#include <omp.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -72,12 +74,20 @@
"| ERROR: Out of memory |\n"\ "| ERROR: Out of memory |\n"\
"o##########################################################o\n" "o##########################################################o\n"
#define TYPERROR "o##########################################################o\n"\
"| ERROR: Invalid file type. |\n"\
"o##########################################################o\n"
#define FOUERROR "o##########################################################o\n"\
"| ERROR: Could not open specified output file. |\n"\
"o##########################################################o\n"
#define RDERROR "o##########################################################o\n"\ #define RDERROR "o##########################################################o\n"\
"| ERROR: Invalid Number of Bytes Read from File. |\n"\ "| ERROR: Invalid number of bytes read from file. |\n"\
"o##########################################################o\n" "o##########################################################o\n"
#define WRTERROR "o##########################################################o\n"\ #define WRTERROR "o##########################################################o\n"\
"| ERROR: Invalid Number of Bytes Written to File. |\n"\ "| ERROR: Invalid number of bytes written to file. |\n"\
"o##########################################################o\n" "o##########################################################o\n"
/*================================================================================================*/ /*================================================================================================*/
@ -427,7 +437,6 @@ parse_opt(int key,
int64_t buff; int64_t buff;
uint8_t i; uint8_t i;
/*-----------------------*\ /*-----------------------*\
! DEFINE REAL VARIABLES: ! ! DEFINE REAL VARIABLES: !
\*-----------------------*/ \*-----------------------*/
@ -435,7 +444,6 @@ parse_opt(int key,
double qt_step_size; double qt_step_size;
float bitrate; float bitrate;
/*-----------------------*\ /*-----------------------*\
! DEFINE CHAR VARIABLES: ! ! DEFINE CHAR VARIABLES: !
\*-----------------------*/ \*-----------------------*/
@ -1069,6 +1077,11 @@ static struct argp argp = {options, parse_opt, 0, doc};
/*================================================================================================*/ /*================================================================================================*/
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
/*-----------------------*\
! DEFINE BOOL VARIABLES: !
\*-----------------------*/
bool delim = false;
/*-----------------------*\ /*-----------------------*\
! DEFINE INT VARIABLES: ! ! DEFINE INT VARIABLES: !
\*-----------------------*/ \*-----------------------*/
@ -1076,20 +1089,29 @@ int main(int argc, char *argv[])
uint8_t i; uint8_t i;
uint8_t error_handle; uint8_t error_handle;
/*-----------------------*\ /*-----------------------*\
! DEFINE REAL VARIABLES: ! ! DEFINE REAL VARIABLES: !
\*-----------------------*/ \*-----------------------*/
double rtype; double rtype, exp;
/*-----------------------*\ /*-----------------------*\
! DEFINE CHAR VARIABLES: ! ! DEFINE CHAR VARIABLES: !
\*-----------------------*/ \*-----------------------*/
char rate[200] = {0}; char rate[200] = {0};
char cli_buffer[1024] = {0};
char cli_verbose[4096] = {0};
char *cli_output;
char *buffer;
unsigned char *input; unsigned char *input;
unsigned char *output; unsigned char *output;
/*-----------------------*\
! DEFINE FILE POINTER: !
\*-----------------------*/
FILE *fp;
/*-----------------------*\ /*-----------------------*\
! DEFINE DER. VARIABLES: ! ! DEFINE DER. VARIABLES: !
\*-----------------------*/ \*-----------------------*/
@ -1111,9 +1133,18 @@ int main(int argc, char *argv[])
goto OUT; goto OUT;
} }
/* Set the number of OpenMP threads. */
#if defined (_OPENMP)
if (arguments.optSet & OMPTH)
omp_set_num_threads((int)arguments.nThreads);
#endif
/* Compress the user supplied data set. */ /* Compress the user supplied data set. */
if (arguments.mode == cli_cmp) if (arguments.mode == cli_cmp)
{ {
/* Ingest the bwccmdl input and set the appropriate cli_ *
* verbose message if the option is set. */
// TODO: Define a universal data structure and implement a reader // TODO: Define a universal data structure and implement a reader
// that ingests different file formats // that ingests different file formats
if ((data = read_eas3(arguments.in)) == NULL) if ((data = read_eas3(arguments.in)) == NULL)
@ -1121,11 +1152,47 @@ int main(int argc, char *argv[])
error_handle = EXIT_FAILURE; error_handle = EXIT_FAILURE;
goto OUT; goto OUT;
} }
if (arguments.verbose == true)
{
strcat(cli_verbose, bwc_header);
strcat(cli_verbose, "--------------------------- I/O --------------------------\n\n");
sprintf(cli_buffer," Input: %s \n", arguments.in);
strcat(cli_verbose, cli_buffer);
memset(cli_buffer, '0', sizeof(char) * 1024);
}
/* Evaluate the appropriate output file. */
if ((arguments.optSet & FLOUT) == 0)
arguments.out = arguments.in;
printf("%s \n", arguments.out);
if ((buffer = strrchr(arguments.out, '.')) == NULL)
{
error_handle = EXIT_FAILURE;
printf(TYPERROR);
goto OUT;
}
cli_output = calloc(strlen(arguments.out) - strlen(buffer) + 1, sizeof(char));
if (cli_output == NULL)
{
error_handle = EXIT_FAILURE;
printf(MEMERROR);
goto OUT;
}
sprintf(cli_output, "%.*s.bwc", (int)(strlen(arguments.out) - strlen(buffer)), arguments.out);
if (arguments.verbose == true)
{
sprintf(cli_buffer," Output: %s \n", cli_output);
strcat(cli_verbose, cli_buffer);
memset(cli_buffer, '0', sizeof(char) * 1024);
}
/* Evaluate the input and output buffer size and initial- * /* Evaluate the input and output buffer size and initial- *
* ize the BigWhoop data and coder structs. */ * ize the BigWhoop data and coder structs. */
size = data->params.ndim1 * data->params.ndim2 * size = data->params.ndim1 * data->params.ndim2 *
data->params.ndim3 * data->params.nts * data->params.ndim3 * data->params.nts *
data->params.npar; data->params.npar;
if (data->params.accuracy == 1) if (data->params.accuracy == 1)
@ -1151,10 +1218,39 @@ int main(int argc, char *argv[])
/* Apply the user supplied compression options using the * /* Apply the user supplied compression options using the *
* appropriate setter functions. */ * appropriate setter functions. */
if((arguments.optSet & QFRMT) != 0) if (arguments.verbose == true)
bwc_set_qm(coder, arguments.Qm); {
strcat(cli_verbose, "\n");
strcat(cli_verbose, "----------------- Compression Parameters -----------------\n");
strcat(cli_verbose, "\n");
}
/*if((arguments.optSet & DWTKL) != 0) if ((arguments.optSet & TILES) != 0)
{
bwc_set_tiles(coder, arguments.tileSize[0],
arguments.tileSize[1],
arguments.tileSize[2],
arguments.tileSize[3], bwc_tile_sizeof);
if (arguments.verbose == true)
{
strcat(cli_verbose," Tile Size: \n");
sprintf(cli_buffer," - Samples in 1.D: %27ld\n"\
" - Samples in 2.D: %27ld\n"\
" - Samples in 3.D: %27ld\n"\
" - Samples in 4.D: %27ld\n", arguments.tileSize[0],
arguments.tileSize[1],
arguments.tileSize[2],
arguments.tileSize[3]);
strcat(cli_verbose, cli_buffer);
memset(cli_buffer, '0', sizeof(char) * 1024);
delim = true;
}
}
// TODO: Implement the kernel setter as a global function
// and define the proper verbose output layout.
/*if ((arguments.optSet & DWTKL) != 0)
{ {
bwc_set_kernels(coder, arguments.dwtKernel[0], bwc_set_kernels(coder, arguments.dwtKernel[0],
arguments.dwtKernel[1], arguments.dwtKernel[1],
@ -1162,61 +1258,160 @@ int main(int argc, char *argv[])
arguments.dwtKernel[3]); arguments.dwtKernel[3]);
}*/ }*/
if((arguments.optSet & DCLVL) != 0) if ((arguments.verbose == true) &&
((arguments.optSet & (DCLVL | PRECS | CBLKS)) != 0))
{
if (delim == true)
{
strcat(cli_verbose, " __________________________________________________________\n");
strcat(cli_verbose, "\n");
}
strcat(cli_verbose, " 1.D | 2.D | 3.D | 4.D\n");
delim = true;
}
if ((arguments.optSet & DCLVL) != 0)
{ {
bwc_set_decomp(coder, arguments.decompLevel[0], bwc_set_decomp(coder, arguments.decompLevel[0],
arguments.decompLevel[1], arguments.decompLevel[1],
arguments.decompLevel[2], arguments.decompLevel[2],
arguments.decompLevel[3]); arguments.decompLevel[3]);
if (arguments.verbose == true)
{
sprintf(cli_buffer, " Decomposition Levels: %18d |%4d |%4d |%4d\n",
arguments.decompLevel[0],
arguments.decompLevel[1],
arguments.decompLevel[2],
arguments.decompLevel[3]);
strcat(cli_verbose, cli_buffer);
memset(cli_buffer, '0', sizeof(char) * 1024);
}
} }
if((arguments.optSet & TILES) != 0) if ((arguments.optSet & PRECS) != 0)
{
bwc_set_tiles(coder, arguments.tileSize[0],
arguments.tileSize[1],
arguments.tileSize[2],
arguments.tileSize[3], bwc_tile_sizeof);
}
if((arguments.optSet & PRECS) != 0)
{ {
bwc_set_precincts(coder, arguments.precSize[0], bwc_set_precincts(coder, arguments.precSize[0],
arguments.precSize[1], arguments.precSize[1],
arguments.precSize[2], arguments.precSize[2],
arguments.precSize[3]); arguments.precSize[3]);
if (arguments.verbose == true)
{
sprintf(cli_buffer, " Precincts [log2]: %18d |%4d |%4d |%4d\n",
arguments.precSize[0],
arguments.precSize[1],
arguments.precSize[2],
arguments.precSize[3]);
strcat(cli_verbose, cli_buffer);
memset(cli_buffer, '0', sizeof(char) * 1024);
}
} }
if((arguments.optSet & CBLKS) != 0) if ((arguments.optSet & CBLKS) != 0)
{ {
bwc_set_codeblocks(coder, arguments.cblkSize[0], bwc_set_codeblocks(coder, arguments.cblkSize[0],
arguments.cblkSize[1], arguments.cblkSize[1],
arguments.cblkSize[2], arguments.cblkSize[2],
arguments.cblkSize[3]); arguments.cblkSize[3]);
if (arguments.verbose == true)
{
sprintf(cli_buffer, " Codeblocks [log2]: %18d |%4d |%4d |%4d\n",
arguments.cblkSize[0],
arguments.cblkSize[1],
arguments.cblkSize[2],
arguments.cblkSize[3]);
strcat(cli_verbose, cli_buffer);
memset(cli_buffer, '0', sizeof(char) * 1024);
}
}
if ((arguments.verbose == true) &&
(delim == true) &&
(((arguments.optSet & QFRMT) != 0) || arguments.erresilience == true))
{
strcat(cli_verbose, " __________________________________________________________\n");
strcat(cli_verbose, "\n");
}
if ((arguments.optSet & QFRMT) != 0)
{
bwc_set_qm(coder, arguments.Qm);
if (arguments.verbose == true)
{
sprintf(cli_buffer, " Q Number Format: %27d\n", arguments.Qm);
strcat(cli_verbose, cli_buffer);
memset(cli_buffer, '0', sizeof(char) * 1024);
delim = true;
}
}
if (arguments.erresilience == true)
{
bwc_set_error_resilience(coder);
if (arguments.verbose == true)
{
sprintf(cli_buffer, " Error Resilience: %27s\n", "true");
strcat(cli_verbose, cli_buffer);
memset(cli_buffer, '0', sizeof(char) * 1024);
delim = true;
}
} }
/* Initialize the rate control string according to the * /* Initialize the rate control string according to the *
* specified bit rate/compression ratio. */ * specified bit rate/compression ratio. */
if((arguments.optSet & BITRT) != 0) if ((arguments.verbose == true) &&
(delim == true))
{
strcat(cli_verbose, " __________________________________________________________\n");
strcat(cli_verbose, "\n");
}
if ((arguments.optSet & BITRT) != 0)
{ {
rtype = 1.0; rtype = 1.0;
exp = 1.0;
} }
else if((arguments.optSet & CMPRT) != 0) else if ((arguments.optSet & CMPRT) != 0)
{ {
rtype = 64.0; rtype = 64.0;
exp = -1.0;
} }
else else
{ {
rtype = 1.0; rtype = 1.0;
exp = 1.0;
arguments.rate[0] = 64; arguments.rate[0] = 64;
} }
for(i = 0; i < 10 && strlen(rate) < 192; ++i) for(i = 0; i < 10 && strlen(rate) < 192; ++i)
{ {
if(arguments.rate[i] > 0) if (arguments.rate[i] > 0)
sprintf(rate + strlen(rate), "%05.3f,", arguments.rate[i]/rtype); {
sprintf(rate + strlen(rate), "%05.3f,", pow(arguments.rate[i]/rtype, exp));
if (arguments.verbose == true)
{
sprintf(cli_buffer, " Quality Layer Nr. %d: %33.2f bpd\n", i,
pow(arguments.rate[i]/rtype, exp));
strcat(cli_verbose, cli_buffer);
}
}
} }
rate[strlen(rate) - 1] = '0'; rate[strlen(rate) - 1] = '0';
if (arguments.verbose == true)
{
memset(cli_buffer, '0', sizeof(char) * 1024);
strcat(cli_verbose, "\n==============================================================\n");
printf("%s", cli_verbose);
}
/* Initialize the rate control string according to the * /* Initialize the rate control string according to the *
* specified bit rate/compression ratio. */ * specified bit rate/compression ratio. */
if (bwc_create_compression(coder, stream, rate) == EXIT_FAILURE) if (bwc_create_compression(coder, stream, rate) == EXIT_FAILURE)
@ -1225,7 +1420,23 @@ int main(int argc, char *argv[])
goto OUT; goto OUT;
} }
bwc_compress(coder, stream); size = bwc_compress(coder, stream);
/* Write the codestream to the speicifed file. */
fp = fopen(cli_output, "wb");
if (fp == NULL)
{
error_handle = EXIT_FAILURE;
printf(FOUERROR);
goto OUT;
}
if (fwrite(stream->out, sizeof(uchar), size, fp) != size)
{
error_handle = EXIT_FAILURE;
printf(WRTERROR);
goto OUT;
}
} }
else if (arguments.mode == cli_dcp) else if (arguments.mode == cli_dcp)
{ {
@ -1257,5 +1468,8 @@ OUT:
if (output != NULL) if (output != NULL)
free(output); free(output);
if (cli_output != NULL)
free(cli_output);
return error_handle; return error_handle;
} }