From d9799506264244fba818ef57600bd466c464240e Mon Sep 17 00:00:00 2001 From: Patrick Vogler Date: Tue, 29 Oct 2024 19:01:33 +0100 Subject: [PATCH] Implemented the compression path with verbose output and support for all options available to the user. --- src/tools/bwccmdl.c | 266 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 240 insertions(+), 26 deletions(-) diff --git a/src/tools/bwccmdl.c b/src/tools/bwccmdl.c index cbc5815..4a5ee0d 100644 --- a/src/tools/bwccmdl.c +++ b/src/tools/bwccmdl.c @@ -48,6 +48,8 @@ #include #include #include +#include +#include #include #include #include @@ -72,12 +74,20 @@ "| ERROR: Out of memory |\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"\ - "| ERROR: Invalid Number of Bytes Read from File. |\n"\ + "| ERROR: Invalid number of bytes read from file. |\n"\ "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" /*================================================================================================*/ @@ -427,7 +437,6 @@ parse_opt(int key, int64_t buff; uint8_t i; - /*-----------------------*\ ! DEFINE REAL VARIABLES: ! \*-----------------------*/ @@ -435,7 +444,6 @@ parse_opt(int key, double qt_step_size; float bitrate; - /*-----------------------*\ ! DEFINE CHAR VARIABLES: ! \*-----------------------*/ @@ -1069,6 +1077,11 @@ static struct argp argp = {options, parse_opt, 0, doc}; /*================================================================================================*/ int main(int argc, char *argv[]) { + /*-----------------------*\ + ! DEFINE BOOL VARIABLES: ! + \*-----------------------*/ + bool delim = false; + /*-----------------------*\ ! DEFINE INT VARIABLES: ! \*-----------------------*/ @@ -1076,20 +1089,29 @@ int main(int argc, char *argv[]) uint8_t i; uint8_t error_handle; - /*-----------------------*\ ! DEFINE REAL VARIABLES: ! \*-----------------------*/ - double rtype; + double rtype, exp; /*-----------------------*\ ! DEFINE CHAR VARIABLES: ! \*-----------------------*/ char rate[200] = {0}; + char cli_buffer[1024] = {0}; + char cli_verbose[4096] = {0}; + + char *cli_output; + char *buffer; unsigned char *input; unsigned char *output; + /*-----------------------*\ + ! DEFINE FILE POINTER: ! + \*-----------------------*/ + FILE *fp; + /*-----------------------*\ ! DEFINE DER. VARIABLES: ! \*-----------------------*/ @@ -1111,9 +1133,18 @@ int main(int argc, char *argv[]) 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. */ 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 // that ingests different file formats if ((data = read_eas3(arguments.in)) == NULL) @@ -1121,11 +1152,47 @@ int main(int argc, char *argv[]) error_handle = EXIT_FAILURE; 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- * * ize the BigWhoop data and coder structs. */ size = data->params.ndim1 * data->params.ndim2 * - data->params.ndim3 * data->params.nts * + data->params.ndim3 * data->params.nts * data->params.npar; if (data->params.accuracy == 1) @@ -1151,10 +1218,39 @@ int main(int argc, char *argv[]) /* Apply the user supplied compression options using the * * appropriate setter functions. */ - if((arguments.optSet & QFRMT) != 0) - bwc_set_qm(coder, arguments.Qm); + if (arguments.verbose == true) + { + 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], arguments.dwtKernel[1], @@ -1162,61 +1258,160 @@ int main(int argc, char *argv[]) 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], arguments.decompLevel[1], arguments.decompLevel[2], 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) - { - bwc_set_tiles(coder, arguments.tileSize[0], - arguments.tileSize[1], - arguments.tileSize[2], - arguments.tileSize[3], bwc_tile_sizeof); - } - - if((arguments.optSet & PRECS) != 0) + if ((arguments.optSet & PRECS) != 0) { bwc_set_precincts(coder, arguments.precSize[0], arguments.precSize[1], arguments.precSize[2], 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], arguments.cblkSize[1], arguments.cblkSize[2], 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 * * 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; + exp = 1.0; } - else if((arguments.optSet & CMPRT) != 0) + else if ((arguments.optSet & CMPRT) != 0) { rtype = 64.0; + exp = -1.0; } else { rtype = 1.0; + exp = 1.0; arguments.rate[0] = 64; } for(i = 0; i < 10 && strlen(rate) < 192; ++i) { - if(arguments.rate[i] > 0) - sprintf(rate + strlen(rate), "%05.3f,", arguments.rate[i]/rtype); + if (arguments.rate[i] > 0) + { + 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'; + 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 * * specified bit rate/compression ratio. */ if (bwc_create_compression(coder, stream, rate) == EXIT_FAILURE) @@ -1225,7 +1420,23 @@ int main(int argc, char *argv[]) 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) { @@ -1257,5 +1468,8 @@ OUT: if (output != NULL) free(output); + if (cli_output != NULL) + free(cli_output); + return error_handle; }