From a814557224662714df6395ab765a292d15738f1b Mon Sep 17 00:00:00 2001 From: Dominik Loidolt <dominik.loidolt@univie.ac.at> Date: Mon, 26 Sep 2022 11:54:31 +0200 Subject: [PATCH] restrict the maximum compression golomb parameter for imagette compression, in order that the compression parameter fit into the imagette compression entity header; refactor the compression check functions --- include/cmp_support.h | 24 ++-- lib/cmp_guess.c | 18 +-- lib/cmp_icu.c | 28 +++-- lib/cmp_rdcu.c | 46 +++---- lib/cmp_support.c | 245 ++++++++++++++++++------------------ test/cmp_icu/test_cmp_icu.c | 35 +++--- test/cmp_icu/test_decmp.c | 54 +++++--- 7 files changed, 237 insertions(+), 213 deletions(-) diff --git a/include/cmp_support.h b/include/cmp_support.h index d0ffbe3..be598aa 100644 --- a/include/cmp_support.h +++ b/include/cmp_support.h @@ -38,11 +38,11 @@ #define MAX_MODEL_VALUE \ 16U /* the maximal model values used in the update equation for the new model */ -/* valid compression parameter ranges for RDCU compression according to PLATO-UVIE-PL-UM-0001 */ +/* valid compression parameter ranges for RDCU/ICU imagette compression according to PLATO-UVIE-PL-UM-0001 */ #define MAX_RDCU_CMP_MODE 4U -#define MIN_RDCU_GOLOMB_PAR 1U -#define MAX_RDCU_GOLOMB_PAR 63U -#define MIN_RDCU_SPILL 2U +#define MIN_IMA_GOLOMB_PAR 1U +#define MAX_IMA_GOLOMB_PAR 63U +#define MIN_IMA_SPILL 2U #define MAX_RDCU_ROUND 2U /* for maximum spill value look at cmp_rdcu_max_spill function */ @@ -91,6 +91,8 @@ #define CMP_DEF_IMA_DIFF_RDCU_UP_MODEL_ADR 0x000000 /* not needed for 1d-differencing cmp_mode */ #define CMP_DEF_IMA_DIFF_RDCU_BUFFER_ADR 0x600000 +enum {ICU_CHECK, RDCU_CHECK}; /* option for the cmp_cfg_imagette_is_invalid() function */ + /* defined compression data product types */ enum cmp_data_type { @@ -237,13 +239,13 @@ int ilog_2(uint32_t x); unsigned int cmp_bit_to_4byte(unsigned int cmp_size_bit); -int cmp_cfg_is_valid(const struct cmp_cfg *cfg); -int cmp_cfg_icu_gen_par_is_valid(const struct cmp_cfg *cfg); -int cmp_cfg_icu_buffers_is_valid(const struct cmp_cfg *cfg); -int cmp_cfg_imagette_is_valid(const struct cmp_cfg *cfg); -int cmp_cfg_fx_cob_is_valid(const struct cmp_cfg *cfg); -int cmp_cfg_aux_is_valid(const struct cmp_cfg *cfg); -uint32_t cmp_rdcu_max_spill(unsigned int golomb_par); +int cmp_cfg_is_invalid(const struct cmp_cfg *cfg); +int cmp_cfg_icu_gen_par_is_invalid(const struct cmp_cfg *cfg); +int cmp_cfg_icu_buffers_is_invalid(const struct cmp_cfg *cfg); +int cmp_cfg_imagette_is_invalid(const struct cmp_cfg *cfg, int rdcu_check); +int cmp_cfg_fx_cob_is_invalid(const struct cmp_cfg *cfg); +int cmp_cfg_aux_is_invalid(const struct cmp_cfg *cfg); +uint32_t cmp_ima_max_spill(unsigned int golomb_par); uint32_t cmp_icu_max_spill(unsigned int cmp_par); int cmp_data_type_valid(enum cmp_data_type data_type); diff --git a/lib/cmp_guess.c b/lib/cmp_guess.c index 40e3ebe..87aec6c 100644 --- a/lib/cmp_guess.c +++ b/lib/cmp_guess.c @@ -83,7 +83,7 @@ uint16_t cmp_guess_model_value(int n_model_updates) uint32_t cmp_rdcu_get_good_spill(unsigned int golomb_par, enum cmp_mode cmp_mode) { - const uint32_t LUT_RDCU_MULIT[MAX_RDCU_GOLOMB_PAR+1] = {0, 8, 16, 23, + const uint32_t LUT_IMA_MULIT[MAX_IMA_GOLOMB_PAR+1] = {0, 8, 16, 23, 30, 36, 44, 51, 58, 64, 71, 77, 84, 90, 97, 108, 115, 121, 128, 135, 141, 148, 155, 161, 168, 175, 181, 188, 194, 201, 207, 214, 229, 236, 242, 250, 256, 263, 269, 276, 283, 290, 296, 303, 310, @@ -91,13 +91,13 @@ uint32_t cmp_rdcu_get_good_spill(unsigned int golomb_par, enum cmp_mode cmp_mode 405, 411, 418, 424, 431, 452 }; if (zero_escape_mech_is_used(cmp_mode)) - return cmp_rdcu_max_spill(golomb_par); + return cmp_ima_max_spill(golomb_par); if (cmp_mode == CMP_MODE_MODEL_MULTI) { - if (golomb_par > MAX_RDCU_GOLOMB_PAR) + if (golomb_par > MAX_IMA_GOLOMB_PAR) return 0; else - return LUT_RDCU_MULIT[golomb_par]; + return LUT_IMA_MULIT[golomb_par]; } if (cmp_mode == CMP_MODE_DIFF_MULTI) @@ -123,7 +123,7 @@ static uint32_t pre_cal_method(struct cmp_cfg *cfg) uint32_t golomb_par_best = 0; uint32_t spill_best = 0; - for (g = MIN_RDCU_GOLOMB_PAR; g < MAX_RDCU_GOLOMB_PAR; g++) { + for (g = MIN_IMA_GOLOMB_PAR; g < MAX_IMA_GOLOMB_PAR; g++) { uint32_t s = cmp_rdcu_get_good_spill(g, cfg->cmp_mode); cfg->golomb_par = g; @@ -171,8 +171,8 @@ static uint32_t brute_force(struct cmp_cfg *cfg) printf("0%%... "); fflush(stdout); - for (g = MIN_RDCU_GOLOMB_PAR; g < MAX_RDCU_GOLOMB_PAR; g++) { - for (s = MIN_RDCU_SPILL; s < cmp_rdcu_max_spill(g); s++) { + for (g = MIN_IMA_GOLOMB_PAR; g < MAX_IMA_GOLOMB_PAR; g++) { + for (s = MIN_IMA_SPILL; s < cmp_ima_max_spill(g); s++) { cfg->golomb_par = g; cfg->spill = s; @@ -211,11 +211,11 @@ static uint32_t brute_force(struct cmp_cfg *cfg) static void add_rdcu_pars_internal(struct cmp_cfg *cfg) { - if (cfg->golomb_par == MIN_RDCU_GOLOMB_PAR) { + if (cfg->golomb_par == MIN_IMA_GOLOMB_PAR) { cfg->ap1_golomb_par = cfg->golomb_par + 1; cfg->ap2_golomb_par = cfg->golomb_par + 2; - } else if (cfg->golomb_par == MAX_RDCU_GOLOMB_PAR) { + } else if (cfg->golomb_par == MAX_IMA_GOLOMB_PAR) { cfg->ap1_golomb_par = cfg->golomb_par - 2; cfg->ap2_golomb_par = cfg->golomb_par - 1; } else { diff --git a/lib/cmp_icu.c b/lib/cmp_icu.c index a05a98f..79d1a64 100644 --- a/lib/cmp_icu.c +++ b/lib/cmp_icu.c @@ -79,7 +79,6 @@ struct encoder_setupt { struct cmp_cfg cmp_cfg_icu_create(enum cmp_data_type data_type, enum cmp_mode cmp_mode, uint32_t model_value, uint32_t lossy_par) { - int cfg_valid; struct cmp_cfg cfg; memset(&cfg, 0, sizeof(cfg)); @@ -89,8 +88,7 @@ struct cmp_cfg cmp_cfg_icu_create(enum cmp_data_type data_type, enum cmp_mode cm cfg.model_value = model_value; cfg.round = lossy_par; - cfg_valid = cmp_cfg_icu_gen_par_is_valid(&cfg); - if (!cfg_valid) + if (cmp_cfg_icu_gen_par_is_invalid(&cfg)) cfg.data_type = DATA_TYPE_UNKNOWN; return cfg; @@ -138,7 +136,7 @@ uint32_t cmp_cfg_icu_buffers(struct cmp_cfg *cfg, void *data_to_compress, cfg->icu_output_buf = compressed_data; cfg->buffer_length = compressed_data_len_samples; - if (!cmp_cfg_icu_buffers_is_valid(cfg)) + if (cmp_cfg_icu_buffers_is_invalid(cfg)) return 0; data_size = cmp_cal_size_of_data(compressed_data_len_samples, cfg->data_type); @@ -173,7 +171,7 @@ int cmp_cfg_icu_imagette(struct cmp_cfg *cfg, uint32_t cmp_par, cfg->golomb_par = cmp_par; cfg->spill = spillover_par; - if (!cmp_cfg_imagette_is_valid(cfg)) + if (cmp_cfg_imagette_is_invalid(cfg, ICU_CHECK)) return -1; return 0; @@ -227,7 +225,7 @@ int cmp_cfg_fx_cob(struct cmp_cfg *cfg, cfg->spill_ecob = spillover_ecob; cfg->spill_fx_cob_variance = spillover_fx_cob_variance; - if (!cmp_cfg_fx_cob_is_valid(cfg)) + if (cmp_cfg_fx_cob_is_invalid(cfg)) return -1; return 0; @@ -268,7 +266,7 @@ int cmp_cfg_aux(struct cmp_cfg *cfg, cfg->spill_variance = spillover_variance; cfg->spill_pixels_error = spillover_pixels_error; - if (!cmp_cfg_aux_is_valid(cfg)) + if (cmp_cfg_aux_is_invalid(cfg)) return -1; return 0; @@ -2250,7 +2248,10 @@ static int pad_bitstream(const struct cmp_cfg *cfg, int cmp_size) if (cmp_size < 0) return cmp_size; - /* no padding in RAW mode; DIFFERENCE ENDIANNESS */ + if (!cfg->icu_output_buf) + return cmp_size; + + /* no padding in RAW mode; ALWAYS BIG-ENDIAN */ if (cfg->cmp_mode == CMP_MODE_RAW) return cmp_size; @@ -2288,6 +2289,9 @@ static int cmp_data_to_big_endian(const struct cmp_cfg *cfg, int cmp_size) if (cmp_size < 0) return cmp_size; + if (!cfg->icu_output_buf) + return cmp_size; + if (cfg->cmp_mode == CMP_MODE_RAW) { if (s & 0x7) /* size must be a multiple of 8 in RAW mode */ return -1; @@ -2343,7 +2347,7 @@ int icu_compress_data(const struct cmp_cfg *cfg) if (cfg->samples > cfg->buffer_length) return CMP_ERROR_SMALL_BUF; - if (!cmp_cfg_is_valid(cfg)) + if (cmp_cfg_is_invalid(cfg)) return -1; if (raw_mode_is_used(cfg->cmp_mode)) { @@ -2425,10 +2429,8 @@ int icu_compress_data(const struct cmp_cfg *cfg) /* LCOV_EXCL_STOP */ } - if (cfg->icu_output_buf) { - cmp_size = pad_bitstream(cfg, cmp_size); - cmp_size = cmp_data_to_big_endian(cfg, cmp_size); - } + cmp_size = pad_bitstream(cfg, cmp_size); + cmp_size = cmp_data_to_big_endian(cfg, cmp_size); return cmp_size; } diff --git a/lib/cmp_rdcu.c b/lib/cmp_rdcu.c index c3ffb7c..6a73545 100644 --- a/lib/cmp_rdcu.c +++ b/lib/cmp_rdcu.c @@ -413,60 +413,60 @@ static int rdcu_cfg_imagette_is_invalid(const struct cmp_cfg *cfg) { int cfg_invalid = 0; - if (cfg->golomb_par < MIN_RDCU_GOLOMB_PAR || - cfg->golomb_par > MAX_RDCU_GOLOMB_PAR) { - debug_print("Error: The selected Golomb parameter: %u is not supported. The Golomb parameter has to be between [%u, %u].\n", - cfg->golomb_par, MIN_RDCU_GOLOMB_PAR, MAX_RDCU_GOLOMB_PAR); + if (cfg->golomb_par < MIN_IMA_GOLOMB_PAR || + cfg->golomb_par > MAX_IMA_GOLOMB_PAR) { + debug_print("Error: The selected Golomb parameter: %u is not supported. The Golomb parameter has to be between [%u, %u].\n", + cfg->golomb_par, MIN_IMA_GOLOMB_PAR, MAX_IMA_GOLOMB_PAR); cfg_invalid++; } - if (cfg->ap1_golomb_par < MIN_RDCU_GOLOMB_PAR || - cfg->ap1_golomb_par > MAX_RDCU_GOLOMB_PAR) { - debug_print("Error: The selected adaptive 1 Golomb parameter: %u is not supported. The Golomb parameter has to be between [%u, %u].\n", - cfg->ap1_golomb_par, MIN_RDCU_GOLOMB_PAR, MAX_RDCU_GOLOMB_PAR); + if (cfg->ap1_golomb_par < MIN_IMA_GOLOMB_PAR || + cfg->ap1_golomb_par > MAX_IMA_GOLOMB_PAR) { + debug_print("Error: The selected adaptive 1 Golomb parameter: %u is not supported. The Golomb parameter has to be between [%u, %u].\n", + cfg->ap1_golomb_par, MIN_IMA_GOLOMB_PAR, MAX_IMA_GOLOMB_PAR); cfg_invalid++; } - if (cfg->ap2_golomb_par < MIN_RDCU_GOLOMB_PAR || - cfg->ap2_golomb_par > MAX_RDCU_GOLOMB_PAR) { + if (cfg->ap2_golomb_par < MIN_IMA_GOLOMB_PAR || + cfg->ap2_golomb_par > MAX_IMA_GOLOMB_PAR) { debug_print("Error: The selected adaptive 2 Golomb parameter: %u is not supported. The Golomb parameter has to be between [%u, %u].\n", - cfg->ap2_golomb_par, MIN_RDCU_GOLOMB_PAR, MAX_RDCU_GOLOMB_PAR); + cfg->ap2_golomb_par, MIN_IMA_GOLOMB_PAR, MAX_IMA_GOLOMB_PAR); cfg_invalid++; } - if (cfg->spill < MIN_RDCU_SPILL) { + if (cfg->spill < MIN_IMA_SPILL) { debug_print("Error: The selected spillover threshold value: %u is too small. Smallest possible spillover value is: %u.\n", - cfg->spill, MIN_RDCU_SPILL); + cfg->spill, MIN_IMA_SPILL); cfg_invalid++; } - if (cfg->spill > cmp_rdcu_max_spill(cfg->golomb_par)) { + if (cfg->spill > cmp_ima_max_spill(cfg->golomb_par)) { debug_print("Error: The selected spillover threshold value: %u is too large for the selected Golomb parameter: %u, the largest possible spillover value is: %u.\n", - cfg->spill, cfg->golomb_par, cmp_rdcu_max_spill(cfg->golomb_par)); + cfg->spill, cfg->golomb_par, cmp_ima_max_spill(cfg->golomb_par)); cfg_invalid++; } - if (cfg->ap1_spill < MIN_RDCU_SPILL) { + if (cfg->ap1_spill < MIN_IMA_SPILL) { debug_print("Error: The selected adaptive 1 spillover threshold value: %u is too small. Smallest possible spillover value is: %u.\n", - cfg->ap1_spill, MIN_RDCU_SPILL); + cfg->ap1_spill, MIN_IMA_SPILL); cfg_invalid++; } - if (cfg->ap1_spill > cmp_rdcu_max_spill(cfg->ap1_golomb_par)) { + if (cfg->ap1_spill > cmp_ima_max_spill(cfg->ap1_golomb_par)) { debug_print("Error: The selected adaptive 1 spillover threshold value: %u is too large for the selected adaptive 1 Golomb parameter: %u, the largest possible adaptive 1 spillover value is: %u.\n", - cfg->ap1_spill, cfg->ap1_golomb_par, cmp_rdcu_max_spill(cfg->ap1_golomb_par)); + cfg->ap1_spill, cfg->ap1_golomb_par, cmp_ima_max_spill(cfg->ap1_golomb_par)); cfg_invalid++; } - if (cfg->ap2_spill < MIN_RDCU_SPILL) { + if (cfg->ap2_spill < MIN_IMA_SPILL) { debug_print("Error: The selected adaptive 2 spillover threshold value: %u is too small. Smallest possible spillover value is: %u.\n", - cfg->ap2_spill, MIN_RDCU_SPILL); + cfg->ap2_spill, MIN_IMA_SPILL); cfg_invalid++; } - if (cfg->ap2_spill > cmp_rdcu_max_spill(cfg->ap2_golomb_par)) { + if (cfg->ap2_spill > cmp_ima_max_spill(cfg->ap2_golomb_par)) { debug_print("Error: The selected adaptive 2 spillover threshold value: %u is too large for the selected adaptive 2 Golomb parameter: %u, the largest possible adaptive 2 spillover value is: %u.\n", - cfg->ap2_spill, cfg->ap2_golomb_par, cmp_rdcu_max_spill(cfg->ap2_golomb_par)); + cfg->ap2_spill, cfg->ap2_golomb_par, cmp_ima_max_spill(cfg->ap2_golomb_par)); cfg_invalid++; } diff --git a/lib/cmp_support.c b/lib/cmp_support.c index 5572a90..17deeed 100644 --- a/lib/cmp_support.c +++ b/lib/cmp_support.c @@ -389,8 +389,8 @@ unsigned int cmp_up_model(unsigned int data, unsigned int model, /** - * @brief get the maximum valid spill threshold value for a RDCU HW compression - * in diff or model mode + * @brief get the maximum valid spill threshold value for a RDCU HW imagette + * compression in diff or model mode * * @param golomb_par Golomb parameter * @@ -398,10 +398,10 @@ unsigned int cmp_up_model(unsigned int data, unsigned int model, * mode compression; 0 if golomb_par is invalid */ -uint32_t cmp_rdcu_max_spill(unsigned int golomb_par) +uint32_t cmp_ima_max_spill(unsigned int golomb_par) { /* the RDCU can only generate 16 bit long code words -> lower max spill needed */ - const uint32_t LUT_MAX_RDCU[MAX_RDCU_GOLOMB_PAR+1] = { 0, 8, 22, 35, 48, + const uint32_t LUT_MAX_RDCU[MAX_IMA_GOLOMB_PAR+1] = { 0, 8, 22, 35, 48, 60, 72, 84, 96, 107, 118, 129, 140, 151, 162, 173, 184, 194, 204, 214, 224, 234, 244, 254, 264, 274, 284, 294, 304, 314, 324, 334, 344, 353, 362, 371, 380, 389, 398, 407, 416, 425, 434, 443, @@ -409,7 +409,7 @@ uint32_t cmp_rdcu_max_spill(unsigned int golomb_par) 569, 578, 587, 596, 605, 614, 623 }; - if (golomb_par > MAX_RDCU_GOLOMB_PAR) + if (golomb_par > MAX_IMA_GOLOMB_PAR) return 0; return LUT_MAX_RDCU[golomb_par]; @@ -458,14 +458,14 @@ unsigned int cmp_bit_to_4byte(unsigned int cmp_size_bit) /** * @brief check if the compression data type, compression mode, model value and - * the lossy rounding parameters are valid for a ICU compression + * the lossy rounding parameters are invalid for a ICU compression * * @param cfg pointer to the compressor configuration * - * @returns 1 if generic compression parameters are valid, otherwise 0 + * @returns 0 if generic compression parameters are valid, otherwise invalid */ -int cmp_cfg_icu_gen_par_is_valid(const struct cmp_cfg *cfg) +int cmp_cfg_icu_gen_par_is_invalid(const struct cmp_cfg *cfg) { int cfg_invalid = 0; @@ -496,22 +496,19 @@ int cmp_cfg_icu_gen_par_is_valid(const struct cmp_cfg *cfg) cfg_invalid++; } - if (cfg_invalid) - return 0; - - return 1; + return cfg_invalid; } /** - * @brief check if the buffer parameters are valid + * @brief check if the buffer parameters are invalid * * @param cfg pointer to the compressor configuration * - * @returns 1 if the buffer parameters are valid, otherwise 0 + * @returns 0 if the buffer parameters are valid, otherwise invalid */ -int cmp_cfg_icu_buffers_is_valid(const struct cmp_cfg *cfg) +int cmp_cfg_icu_buffers_is_invalid(const struct cmp_cfg *cfg) { int cfg_invalid = 0; @@ -572,65 +569,81 @@ int cmp_cfg_icu_buffers_is_valid(const struct cmp_cfg *cfg) } } - if (cfg_invalid) - return 0; - - return 1; + return cfg_invalid; } /** - * @brief check if the combination of the different compression parameters is valid + * @brief check if the combination of the different compression parameters is invalid * * @param cmp_par compression parameter * @param spill spillover threshold parameter * @param cmp_mode compression mode + * @param data_type compression data type * @param par_name string describing the use of the compression par. for * debug messages (can be NULL) * - * @returns 1 if the parameter combination is valid, otherwise 0 + * @returns 0 if the parameter combination is valid, otherwise the combination is invalid */ -static int cmp_pars_are_valid(uint32_t cmp_par, uint32_t spill, enum cmp_mode cmp_mode, - char *par_name) +static int cmp_pars_are_invalid(uint32_t cmp_par, uint32_t spill, enum cmp_mode cmp_mode, + enum cmp_data_type data_type, char *par_name) { int cfg_invalid = 0; + uint32_t min_golomb_par; + uint32_t max_golomb_par; + uint32_t min_spill; + uint32_t max_spill; if (!par_name) par_name = ""; + /* The maximum compression parameter for imagette data are smaller to + * fit into the imagette compression entity header */ + if (cmp_imagette_data_type_is_used(data_type)) { + min_golomb_par = MIN_IMA_GOLOMB_PAR; + max_golomb_par = MAX_IMA_GOLOMB_PAR; + min_spill = MIN_IMA_SPILL; + max_spill = cmp_ima_max_spill(cmp_par); + } else { + min_golomb_par = MIN_ICU_GOLOMB_PAR; + max_golomb_par = MAX_ICU_GOLOMB_PAR; + min_spill = MIN_ICU_SPILL; + max_spill = cmp_icu_max_spill(cmp_par); + } + + switch (cmp_mode) { case CMP_MODE_RAW: /* no checks needed */ break; - case CMP_MODE_STUFF: - if (cmp_par > MAX_STUFF_CMP_PAR) { - debug_print("Error: The selected %s stuff mode compression parameter: %u is too large, the largest possible value in the selected compression mode is: %u.\n", - par_name, cmp_par, MAX_STUFF_CMP_PAR); - cfg_invalid++; - } - break; case CMP_MODE_DIFF_ZERO: case CMP_MODE_DIFF_MULTI: case CMP_MODE_MODEL_ZERO: case CMP_MODE_MODEL_MULTI: - if (cmp_par < MIN_ICU_GOLOMB_PAR || - cmp_par > MAX_ICU_GOLOMB_PAR) { + if (cmp_par < min_golomb_par || cmp_par > max_golomb_par) { debug_print("Error: The selected %s compression parameter: %u is not supported. The compression parameter has to be between [%u, %u].\n", - par_name, cmp_par, MIN_ICU_GOLOMB_PAR, MAX_ICU_GOLOMB_PAR); + par_name, cmp_par, min_golomb_par, max_golomb_par); cfg_invalid++; } - if (spill < MIN_ICU_SPILL) { + if (spill < min_spill) { debug_print("Error: The selected %s spillover threshold value: %u is too small. Smallest possible spillover value is: %u.\n", - par_name, spill, MIN_ICU_SPILL); + par_name, spill, min_spill); cfg_invalid++; } - if (spill > cmp_icu_max_spill(cmp_par)) { + if (spill > max_spill) { debug_print("Error: The selected %s spillover threshold value: %u is too large for the selected %s compression parameter: %u, the largest possible spillover value in the selected compression mode is: %u.\n", - par_name, spill, par_name, cmp_par, cmp_icu_max_spill(cmp_par)); + par_name, spill, par_name, cmp_par, max_spill); cfg_invalid++; } + break; + case CMP_MODE_STUFF: + if (cmp_par > MAX_STUFF_CMP_PAR) { + debug_print("Error: The selected %s stuff mode compression parameter: %u is too large, the largest possible value in the selected compression mode is: %u.\n", + par_name, cmp_par, MAX_STUFF_CMP_PAR); + cfg_invalid++; + } break; default: debug_print("Error: The compression mode is not supported.\n"); @@ -638,24 +651,24 @@ static int cmp_pars_are_valid(uint32_t cmp_par, uint32_t spill, enum cmp_mode cm break; } - if (cfg_invalid) - return 0; - - return 1; + return cfg_invalid; } /** - * @brief check if the imagette specific compression parameters are valid + * @brief check if the imagette specific compression parameters are invalid * - * @param cfg pointer to the compressor configuration + * @param cfg pointer to the compressor configuration + * @param rdcu_check set to non-zero if a check for a imagette RDCU compression + * should be done; zero for imagette ICU compression * - * @returns 1 if the imagette specific parameters are valid, otherwise 0 + * @returns 0 if the imagette specific parameters are valid, otherwise invalid */ -int cmp_cfg_imagette_is_valid(const struct cmp_cfg *cfg) +int cmp_cfg_imagette_is_invalid(const struct cmp_cfg *cfg, int rdcu_check) { int cfg_invalid = 0; + enum cmp_mode cmp_mode; if (!cfg) return 0; @@ -665,35 +678,37 @@ int cmp_cfg_imagette_is_valid(const struct cmp_cfg *cfg) cfg_invalid++; } - if (!cmp_pars_are_valid(cfg->golomb_par, cfg->spill, cfg->cmp_mode, - "imagette")) - cfg_invalid++; - - if (cmp_ap_imagette_data_type_is_used(cfg->data_type)) { - if (!cmp_pars_are_valid(cfg->ap1_golomb_par, cfg->ap1_spill, - cfg->cmp_mode, "adaptive 1 imagette")) - cfg_invalid++; - if (!cmp_pars_are_valid(cfg->ap2_golomb_par, cfg->ap2_spill, - cfg->cmp_mode, "adaptive 2 imagette")) - cfg_invalid++; + /* The RDCU needs valid compression parameters also in RAW_MODE */ + if (rdcu_check && cfg->cmp_mode == CMP_MODE_RAW) + cmp_mode = CMP_MODE_MODEL_ZERO; + else + cmp_mode = cfg->cmp_mode; + + cfg_invalid += cmp_pars_are_invalid(cfg->golomb_par, cfg->spill, cmp_mode, + cfg->data_type, "imagette"); + + /* for the RDCU the adaptive parameters have to be always valid */ + if (rdcu_check || cmp_ap_imagette_data_type_is_used(cfg->data_type)) { + cfg_invalid += cmp_pars_are_invalid(cfg->ap1_golomb_par, cfg->ap1_spill, + cmp_mode, cfg->data_type, "adaptive 1 imagette"); + cfg_invalid += cmp_pars_are_invalid(cfg->ap2_golomb_par, cfg->ap2_spill, + cmp_mode, cfg->data_type, "adaptive 2 imagette"); } - if (cfg_invalid) - return 0; - - return 1; + return cfg_invalid; } /** - * @brief check if the flux/center of brightness specific compression parameters are valid + * @brief check if the flux/center of brightness specific compression parameters + * are invalid * * @param cfg pointer to the compressor configuration * - * @returns 1 if the flux/center of brightness specific parameters are valid, otherwise 0 + * @returns 0 if the flux/center of brightness specific parameters are valid, otherwise invalid */ -int cmp_cfg_fx_cob_is_valid(const struct cmp_cfg *cfg) +int cmp_cfg_fx_cob_is_invalid(const struct cmp_cfg *cfg) { int cfg_invalid = 0; int check_exp_flags = 0, check_ncob = 0, check_efx = 0, check_ecob = 0, check_var = 0; @@ -706,8 +721,8 @@ int cmp_cfg_fx_cob_is_valid(const struct cmp_cfg *cfg) cfg_invalid++; } /* flux parameter is needed for every fx_cob data_type */ - if (!cmp_pars_are_valid(cfg->cmp_par_fx, cfg->spill_fx, cfg->cmp_mode, "flux")) - cfg_invalid++; + cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_fx, cfg->spill_fx, + cfg->cmp_mode, cfg->data_type, "flux"); switch (cfg->data_type) { case DATA_TYPE_S_FX: @@ -766,39 +781,37 @@ int cmp_cfg_fx_cob_is_valid(const struct cmp_cfg *cfg) break; } - if (check_exp_flags && !cmp_pars_are_valid(cfg->cmp_par_exp_flags, - cfg->spill_exp_flags, cfg->cmp_mode, "exposure flags")) - cfg_invalid++; - if (check_ncob && !cmp_pars_are_valid(cfg->cmp_par_ncob, cfg->spill_ncob, - cfg->cmp_mode, "center of brightness")) - cfg_invalid++; - if (check_efx && !cmp_pars_are_valid(cfg->cmp_par_efx, cfg->spill_efx, - cfg->cmp_mode, "extended flux")) - cfg_invalid++; - if (check_ecob && !cmp_pars_are_valid(cfg->cmp_par_ecob, cfg->spill_ecob, - cfg->cmp_mode, "extended center of brightness")) - cfg_invalid++; - if (check_var && !cmp_pars_are_valid(cfg->cmp_par_fx_cob_variance, - cfg->spill_fx_cob_variance, cfg->cmp_mode, "flux COB varianc")) - cfg_invalid++; - - if (cfg_invalid) - return 0; - - return 1; + if (check_exp_flags) + cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_exp_flags, cfg->spill_exp_flags, + cfg->cmp_mode, cfg->data_type, "exposure flags"); + if (check_ncob) + cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_ncob, cfg->spill_ncob, + cfg->cmp_mode, cfg->data_type, "center of brightness"); + if (check_efx) + cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_efx, cfg->spill_efx, + cfg->cmp_mode, cfg->data_type, "extended flux"); + if (check_ecob) + cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_ecob, cfg->spill_ecob, + cfg->cmp_mode, cfg->data_type, "extended center of brightness"); + if (check_var) + cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_fx_cob_variance, + cfg->spill_fx_cob_variance, cfg->cmp_mode, cfg->data_type, "flux COB varianc"); + + return cfg_invalid; } /** - * @brief check if the auxiliary science specific compression parameters are valid + * @brief check if the auxiliary science specific compression parameters are invalid * * @param cfg pointer to the compressor configuration * - * @returns 1 if the auxiliary science specific parameters are valid, otherwise 0 + * @returns 0 if the auxiliary science specific parameters are valid, otherwise + * invalid * TODO: implemented DATA_TYPE_F_CAM_OFFSET and DATA_TYPE_F_CAM_BACKGROUND */ -int cmp_cfg_aux_is_valid(const struct cmp_cfg *cfg) +int cmp_cfg_aux_is_invalid(const struct cmp_cfg *cfg) { int cfg_invalid = 0; @@ -810,63 +823,49 @@ int cmp_cfg_aux_is_valid(const struct cmp_cfg *cfg) cfg_invalid++; } - if (!cmp_pars_are_valid(cfg->cmp_par_mean, cfg->spill_mean, - cfg->cmp_mode, "mean")) - cfg_invalid++; - if (!cmp_pars_are_valid(cfg->cmp_par_variance, cfg->spill_variance, - cfg->cmp_mode, "variance")) - cfg_invalid++; + cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_mean, cfg->spill_mean, + cfg->cmp_mode, cfg->data_type, "mean"); + cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_variance, cfg->spill_variance, + cfg->cmp_mode, cfg->data_type, "variance"); + /* if (cfg->data_type != DATA_TYPE_OFFSET && cfg->data_type != DATA_TYPE_F_CAM_OFFSET) */ if (cfg->data_type != DATA_TYPE_OFFSET) - if (!cmp_pars_are_valid(cfg->cmp_par_pixels_error, cfg->spill_pixels_error, - cfg->cmp_mode, "outlier pixls num")) - cfg_invalid++; - - if (cfg_invalid) - return 0; + cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_pixels_error, cfg->spill_pixels_error, + cfg->cmp_mode, cfg->data_type, "outlier pixls num"); - return 1; + return cfg_invalid; } /** - * @brief check if a compression configuration is valid + * @brief check if a compression configuration is invalid * * @param cfg pointer to the compressor configuration * - * @returns 1 if the compression configuration is valid, otherwise 0 + * @returns 0 if the compression configuration is valid, otherwise invalid */ -int cmp_cfg_is_valid(const struct cmp_cfg *cfg) +int cmp_cfg_is_invalid(const struct cmp_cfg *cfg) { int cfg_invalid = 0; if (!cfg) return 0; - if (!cmp_cfg_icu_gen_par_is_valid(cfg)) - cfg_invalid++; + cfg_invalid += cmp_cfg_icu_gen_par_is_invalid(cfg); - if (!cmp_cfg_icu_buffers_is_valid(cfg)) - cfg_invalid++; + cfg_invalid += cmp_cfg_icu_buffers_is_invalid(cfg); - if (cmp_imagette_data_type_is_used(cfg->data_type)) { - if (!cmp_cfg_imagette_is_valid(cfg)) - cfg_invalid++; - } else if (cmp_fx_cob_data_type_is_used(cfg->data_type)) { - if (!cmp_cfg_fx_cob_is_valid(cfg)) - cfg_invalid++; - } else if (cmp_aux_data_type_is_used(cfg->data_type)) { - if (!cmp_cfg_aux_is_valid(cfg)) - cfg_invalid++; - } else { + if (cmp_imagette_data_type_is_used(cfg->data_type)) + cfg_invalid += cmp_cfg_imagette_is_invalid(cfg, ICU_CHECK); + else if (cmp_fx_cob_data_type_is_used(cfg->data_type)) + cfg_invalid += cmp_cfg_fx_cob_is_invalid(cfg); + else if (cmp_aux_data_type_is_used(cfg->data_type)) + cfg_invalid += cmp_cfg_aux_is_invalid(cfg); + else cfg_invalid++; - } - - if (cfg_invalid) - return 0; - return 1; + return cfg_invalid; } diff --git a/test/cmp_icu/test_cmp_icu.c b/test/cmp_icu/test_cmp_icu.c index 3eae4be..65ab545 100644 --- a/test/cmp_icu/test_cmp_icu.c +++ b/test/cmp_icu/test_cmp_icu.c @@ -1,6 +1,5 @@ -#include "cmp_support.h" -#include <string.h> #include <stdlib.h> + #if defined __has_include # if __has_include(<time.h>) # include <time.h> @@ -436,8 +435,8 @@ void test_cmp_cfg_icu_imagette(void) /* lowest values 1d/model mode */ cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_ZERO, 0, CMP_LOSSLESS); - cmp_par = MIN_ICU_GOLOMB_PAR; - spillover_par = MIN_ICU_SPILL; + cmp_par = MIN_IMA_GOLOMB_PAR; + spillover_par = MIN_IMA_SPILL; error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); TEST_ASSERT_FALSE(error); TEST_ASSERT_EQUAL_INT(cfg.golomb_par, 1); @@ -445,12 +444,12 @@ void test_cmp_cfg_icu_imagette(void) /* highest values 1d/model mode */ cfg = cmp_cfg_icu_create(DATA_TYPE_F_CAM_IMAGETTE, CMP_MODE_DIFF_MULTI, 16, CMP_LOSSLESS); - cmp_par = MAX_ICU_GOLOMB_PAR; - spillover_par = cmp_icu_max_spill(cmp_par); + cmp_par = MAX_IMA_GOLOMB_PAR; + spillover_par = cmp_ima_max_spill(cmp_par); error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); TEST_ASSERT_FALSE(error); - TEST_ASSERT_EQUAL_INT(cfg.golomb_par, 0xFFFF); - TEST_ASSERT_EQUAL_INT(cfg.spill, 1048545); + TEST_ASSERT_EQUAL_INT(cfg.golomb_par, MAX_IMA_GOLOMB_PAR); + TEST_ASSERT_EQUAL_INT(cfg.spill, cmp_ima_max_spill(MAX_IMA_GOLOMB_PAR)); /* wrong data type test */ for (data_type = 0; data_type <= DATA_TYPE_F_CAM_BACKGROUND; data_type++) { @@ -461,8 +460,8 @@ void test_cmp_cfg_icu_imagette(void) data_type == DATA_TYPE_F_CAM_IMAGETTE) { TEST_ASSERT_FALSE(error); TEST_ASSERT_EQUAL_INT(data_type, cfg.data_type); - TEST_ASSERT_EQUAL_INT(cfg.golomb_par, 0xFFFF); - TEST_ASSERT_EQUAL_INT(cfg.spill, 1048545); + TEST_ASSERT_EQUAL_INT(cfg.golomb_par, MAX_IMA_GOLOMB_PAR); + TEST_ASSERT_EQUAL_INT(cfg.spill, cmp_ima_max_spill(MAX_IMA_GOLOMB_PAR)); } else { TEST_ASSERT_TRUE(error); } @@ -472,8 +471,8 @@ void test_cmp_cfg_icu_imagette(void) /* cmp_par to big */ cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_MULTI, 16, CMP_LOSSLESS); - cmp_par = MAX_ICU_GOLOMB_PAR + 1; - spillover_par = MIN_ICU_SPILL; + cmp_par = MAX_IMA_GOLOMB_PAR + 1; + spillover_par = MIN_IMA_SPILL; error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); TEST_ASSERT_TRUE(error); /* ignore in RAW MODE */ @@ -483,8 +482,8 @@ void test_cmp_cfg_icu_imagette(void) /* cmp_par to small */ cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_MULTI, 16, CMP_LOSSLESS); - cmp_par = MIN_ICU_GOLOMB_PAR - 1; - spillover_par = MIN_ICU_SPILL; + cmp_par = MIN_IMA_GOLOMB_PAR - 1; + spillover_par = MIN_IMA_SPILL; error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); TEST_ASSERT_TRUE(error); /* ignore in RAW MODE */ @@ -494,8 +493,8 @@ void test_cmp_cfg_icu_imagette(void) /* spillover_par to big */ cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_MULTI, 16, CMP_LOSSLESS); - cmp_par = MIN_ICU_GOLOMB_PAR; - spillover_par = cmp_icu_max_spill(cmp_par)+1; + cmp_par = MIN_IMA_GOLOMB_PAR; + spillover_par = cmp_ima_max_spill(cmp_par)+1; error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); TEST_ASSERT_TRUE(error); /* ignore in RAW MODE */ @@ -505,8 +504,8 @@ void test_cmp_cfg_icu_imagette(void) /* spillover_par to small */ cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_DIFF_ZERO, 0, CMP_LOSSLESS); - cmp_par = MAX_ICU_GOLOMB_PAR; - spillover_par = MIN_ICU_SPILL -1 ; + cmp_par = MAX_IMA_GOLOMB_PAR; + spillover_par = MIN_IMA_SPILL -1 ; error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); TEST_ASSERT_TRUE(error); /* ignore in RAW MODE */ diff --git a/test/cmp_icu/test_decmp.c b/test/cmp_icu/test_decmp.c index cb00bb0..244bbe8 100644 --- a/test/cmp_icu/test_decmp.c +++ b/test/cmp_icu/test_decmp.c @@ -49,9 +49,8 @@ size_t icu_compress_data_entity(struct cmp_entity *ent, const struct cmp_cfg *cf if (cmp_size_bits < 0) return 0; - /* XXX overwrite the size of the compression entity with the size of the - * actual size of the compressed data */ - /* not all allocated memory is normally needed */ + /* XXX overwrite the size of the compression entity with the size of the actual + * size of the compressed data; not all allocated memory is normally used */ s = cmp_ent_create(ent, cfg->data_type, cfg->cmp_mode == CMP_MODE_RAW, cmp_bit_to_4byte(cmp_size_bits)); @@ -161,9 +160,28 @@ void test_re_map_to_pos(void) } +void test_rice_decoder(void) +{ + int cw_len; + uint32_t code_word; + unsigned int m = ~0;/* we don't need this value */ + unsigned int log2_m; + unsigned int decoded_cw; + + /* test log_2 to big */ + code_word = 0xE0000000; + log2_m = 33; + cw_len = rice_decoder(code_word, m, log2_m, &decoded_cw); + TEST_ASSERT_EQUAL(0, cw_len); + log2_m = UINT_MAX; + cw_len = rice_decoder(code_word, m, log2_m, &decoded_cw); + TEST_ASSERT_EQUAL(0, cw_len); +} + + void test_decode_normal(void) { - uint32_t decoded_value; + uint32_t decoded_value = ~0; int stream_pos, sample; /* compressed data from 0 to 6; */ uint32_t cmp_data[] = {0x5BBDF7E0}; @@ -176,7 +194,6 @@ void test_decode_normal(void) setup.encoder_par2 = ilog_2(setup.encoder_par1); setup.bitstream_adr = cmp_data; setup.max_stream_len = 32; - setup.max_cw_len = 16; stream_pos = 0; for (sample = 0; sample < 7; sample++) { @@ -190,7 +207,7 @@ void test_decode_normal(void) void test_decode_zero(void) { - uint32_t decoded_value; + uint32_t decoded_value = ~0; int stream_pos; uint32_t cmp_data[] = {0x88449FE0}; struct decoder_setup setup = {0}; @@ -221,7 +238,7 @@ void test_decode_zero(void) void test_decode_multi(void) { - uint32_t decoded_value; + uint32_t decoded_value = ~0; int stream_pos; uint32_t cmp_data[] = {0x16B66DF8, 0x84360000}; struct decoder_setup setup = {0}; @@ -297,7 +314,6 @@ void test_decompress_imagette_model(void) -#define CMP_PAR_UNUSED 0 /*TODO: remove this*/ #define DATA_SAMPLES 5 void test_cmp_decmp_s_fx_diff(void) { @@ -471,8 +487,8 @@ void test_imagette_random(void) NULL, compressed_data_len_samples); TEST_ASSERT_TRUE(cmp_data_size); - uint32_t golomb_par = my_random(MIN_RDCU_GOLOMB_PAR, MAX_RDCU_GOLOMB_PAR); - uint32_t max_spill = cmp_icu_max_spill(golomb_par); + uint32_t golomb_par = my_random(MIN_IMA_GOLOMB_PAR, MAX_IMA_GOLOMB_PAR); + uint32_t max_spill = cmp_ima_max_spill(golomb_par); TEST_ASSERT(max_spill > 1); uint32_t spill = my_random(2, max_spill); @@ -663,9 +679,9 @@ void test_random_compression_decompression(void) /* cfg.round = my_random(0,3); /1* XXX *1/ */ cfg.round = 0; - cfg.golomb_par = my_random(MIN_RDCU_GOLOMB_PAR, MAX_RDCU_GOLOMB_PAR); - cfg.ap1_golomb_par = my_random(MIN_RDCU_GOLOMB_PAR, MAX_RDCU_GOLOMB_PAR); - cfg.ap2_golomb_par = my_random(MIN_RDCU_GOLOMB_PAR, MAX_RDCU_GOLOMB_PAR); + cfg.golomb_par = my_random(MIN_IMA_GOLOMB_PAR, MAX_IMA_GOLOMB_PAR); + cfg.ap1_golomb_par = my_random(MIN_IMA_GOLOMB_PAR, MAX_IMA_GOLOMB_PAR); + cfg.ap2_golomb_par = my_random(MIN_IMA_GOLOMB_PAR, MAX_IMA_GOLOMB_PAR); cfg.cmp_par_exp_flags = my_random(MIN_ICU_GOLOMB_PAR, MAX_ICU_GOLOMB_PAR); cfg.cmp_par_fx = my_random(MIN_ICU_GOLOMB_PAR, MAX_ICU_GOLOMB_PAR); cfg.cmp_par_ncob = my_random(MIN_ICU_GOLOMB_PAR, MAX_ICU_GOLOMB_PAR); @@ -676,9 +692,9 @@ void test_random_compression_decompression(void) cfg.cmp_par_variance = my_random(MIN_ICU_GOLOMB_PAR, MAX_ICU_GOLOMB_PAR); cfg.cmp_par_pixels_error = my_random(MIN_ICU_GOLOMB_PAR, MAX_ICU_GOLOMB_PAR); - cfg.spill = my_random(MIN_RDCU_SPILL, cmp_icu_max_spill(cfg.golomb_par)); - cfg.ap1_spill = my_random(MIN_RDCU_SPILL, cmp_icu_max_spill(cfg.ap1_golomb_par)); - cfg.ap2_spill = my_random(MIN_RDCU_SPILL, cmp_icu_max_spill(cfg.ap2_golomb_par)); + cfg.spill = my_random(MIN_IMA_SPILL, cmp_ima_max_spill(cfg.golomb_par)); + cfg.ap1_spill = my_random(MIN_IMA_SPILL, cmp_ima_max_spill(cfg.ap1_golomb_par)); + cfg.ap2_spill = my_random(MIN_IMA_SPILL, cmp_ima_max_spill(cfg.ap2_golomb_par)); if (!rdcu_supported_data_type_is_used(cfg.data_type)) { cfg.spill_exp_flags = my_random(MIN_ICU_SPILL, cmp_icu_max_spill(cfg.cmp_par_exp_flags)); cfg.spill_fx = my_random(MIN_ICU_SPILL, cmp_icu_max_spill(cfg.cmp_par_fx)); @@ -734,3 +750,9 @@ void test_random_compression_decompression(void) } } + +void test_decompression_error_cases(void) +{ + /* error cases model decompression without a model Buffer */ + /* error cases wrong cmp parameter; model value; usw */ +} -- GitLab