From 1da2d6052eca2d0dd172863108cee715079abe13 Mon Sep 17 00:00:00 2001 From: Dominik Loidolt <dominik.loidolt@univie.ac.at> Date: Thu, 1 Sep 2022 12:39:39 +0200 Subject: [PATCH] fix a bug in the compress_multi_entry_hdr() function reduce the max golomb_par (cmp_par) because the entity field has 16 bits split get_max_spill() function in 2 for RDCU cmp_rdcu_max_spill() and ICU cmp_icu_max_spill() fix some typos refactoring pad_bitstream() and cmp_data_to_big_endian() configure_encoder_setup() functions refactoring RAW compression update tests --- include/cmp_icu.h | 10 +- include/cmp_rdcu.h | 4 +- include/cmp_support.h | 19 +- lib/cmp_guess.c | 4 +- lib/cmp_icu.c | 202 +++-- lib/cmp_rdcu.c | 53 +- lib/cmp_support.c | 143 +-- test/cmp_icu/test_cmp_icu.c | 1676 ++++++++++++++++++++++++++++++++++- 8 files changed, 1895 insertions(+), 216 deletions(-) diff --git a/include/cmp_icu.h b/include/cmp_icu.h index 01e528c..8b68fcb 100644 --- a/include/cmp_icu.h +++ b/include/cmp_icu.h @@ -22,15 +22,7 @@ #include <cmp_support.h> - -/* return code if the bitstream buffer is too small to store the whole bitstream */ -#define CMP_ERROR_SAMLL_BUF -2 - -/* return code if the value or the model is bigger than the max_used_bits - * parameter allows - */ -#define CMP_ERROR_HIGH_VALUE -3 - +#define CMP_PAR_UNUSED 0 /* create and setup a compression configuration */ struct cmp_cfg cmp_cfg_icu_create(enum cmp_data_type data_type, enum cmp_mode cmp_mode, diff --git a/include/cmp_rdcu.h b/include/cmp_rdcu.h index 780c869..93da3d0 100644 --- a/include/cmp_rdcu.h +++ b/include/cmp_rdcu.h @@ -47,8 +47,6 @@ int rdcu_cfg_imagette(struct cmp_cfg *cfg, uint32_t ap1_golomb_par, uint32_t ap1_spillover_par, uint32_t ap2_golomb_par, uint32_t ap2_spillover_par); -int rdcu_cmp_cfg_is_invalid(const struct cmp_cfg *cfg); - int rdcu_compress_data(const struct cmp_cfg *cfg); int rdcu_read_cmp_status(struct cmp_status *status); @@ -64,4 +62,6 @@ int rdcu_interrupt_compression(void); void rdcu_enable_interrput_signal(void); void rdcu_disable_interrput_signal(void); +int rdcu_cmp_cfg_is_invalid(const struct cmp_cfg *cfg); + #endif /* _CMP_RDCU_H_ */ diff --git a/include/cmp_support.h b/include/cmp_support.h index f5e0b38..5c85a99 100644 --- a/include/cmp_support.h +++ b/include/cmp_support.h @@ -23,6 +23,14 @@ #include <stddef.h> +/* return code if the bitstream buffer is too small to store the whole bitstream */ +#define CMP_ERROR_SAMLL_BUF -2 + +/* return code if the value or the model is bigger than the max_used_bits + * parameter allows + */ +#define CMP_ERROR_HIGH_VALUE -3 + #define CMP_LOSSLESS 0 #define CMP_PAR_UNUNSED 0 @@ -36,13 +44,13 @@ #define MAX_RDCU_GOLOMB_PAR 63U #define MIN_RDCU_SPILL 2U #define MAX_RDCU_ROUND 2U -/* for maximum spill value look at get_max_spill function */ +/* for maximum spill value look at cmp_rdcu_max_spill function */ /* valid compression parameter ranges for ICU compression */ #define MIN_ICU_GOLOMB_PAR 1U -#define MAX_ICU_GOLOMB_PAR 0x80000000U +#define MAX_ICU_GOLOMB_PAR UINT16_MAX /* the compression entity dos not allow larger values */ #define MIN_ICU_SPILL 2U -/* for maximum spill value look at get_max_spill function */ +/* for maximum spill value look at cmp_icu_max_spill function */ #define MAX_ICU_ROUND 3U #define MAX_STUFF_CMP_PAR 32U @@ -86,7 +94,7 @@ /* defined compression data product types */ enum cmp_data_type { - DATA_TYPE_UNKOWN, + DATA_TYPE_UNKNOWN, DATA_TYPE_IMAGETTE, DATA_TYPE_IMAGETTE_ADAPTIVE, DATA_TYPE_SAT_IMAGETTE, @@ -235,7 +243,8 @@ 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 get_max_spill(unsigned int golomb_par, enum cmp_data_type); +uint32_t cmp_rdcu_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); int rdcu_supported_data_type_is_used(enum cmp_data_type data_type); diff --git a/lib/cmp_guess.c b/lib/cmp_guess.c index 3107aaf..40e3ebe 100644 --- a/lib/cmp_guess.c +++ b/lib/cmp_guess.c @@ -91,7 +91,7 @@ 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 get_max_spill(golomb_par, DATA_TYPE_IMAGETTE); + return cmp_rdcu_max_spill(golomb_par); if (cmp_mode == CMP_MODE_MODEL_MULTI) { if (golomb_par > MAX_RDCU_GOLOMB_PAR) @@ -172,7 +172,7 @@ static uint32_t brute_force(struct cmp_cfg *cfg) fflush(stdout); for (g = MIN_RDCU_GOLOMB_PAR; g < MAX_RDCU_GOLOMB_PAR; g++) { - for (s = MIN_RDCU_SPILL; s < get_max_spill(g, cfg->data_type); s++) { + for (s = MIN_RDCU_SPILL; s < cmp_rdcu_max_spill(g); s++) { cfg->golomb_par = g; cfg->spill = s; diff --git a/lib/cmp_icu.c b/lib/cmp_icu.c index 2d11006..c6d4a27 100644 --- a/lib/cmp_icu.c +++ b/lib/cmp_icu.c @@ -39,6 +39,10 @@ #include <cmp_icu.h> +/* maximum used bits registry */ +extern struct cmp_max_used_bits max_used_bits; + + /* pointer to a code word generation function */ typedef uint32_t (*generate_cw_f_pt)(uint32_t value, uint32_t encoder_par1, uint32_t encoder_par2, uint32_t *cw); @@ -46,7 +50,7 @@ typedef uint32_t (*generate_cw_f_pt)(uint32_t value, uint32_t encoder_par1, /* structure to hold a setup to encode a value */ struct encoder_setupt { - generate_cw_f_pt generate_cw_f; /* pointer to the code word generation function */ + generate_cw_f_pt generate_cw_f; /* pointer to the code word encoder */ int (*encode_method_f)(uint32_t data, uint32_t model, int stream_len, const struct encoder_setupt *setup); /* pointer to the encoding function */ uint32_t *bitstream_adr; /* start address of the compressed data bitstream */ @@ -60,15 +64,15 @@ struct encoder_setupt { /** - * @brief create a ICU compression configuration + * @brief create an ICU compression configuration * - * @param data_type compression data product types + * @param data_type compression data product type * @param cmp_mode compression mode - * @param model_value model weighting parameter (only need for model compression mode) + * @param model_value model weighting parameter (only needed for model compression mode) * @param lossy_par lossy rounding parameter (use CMP_LOSSLESS for lossless compression) * - * @returns compression configuration containing the chosen parameters; - * on error the data_type record is set to DATA_TYPE_UNKOWN + * @returns a compression configuration containing the chosen parameters; + * on error the data_type record is set to DATA_TYPE_UNKNOWN */ struct cmp_cfg cmp_cfg_icu_create(enum cmp_data_type data_type, enum cmp_mode cmp_mode, @@ -86,20 +90,20 @@ struct cmp_cfg cmp_cfg_icu_create(enum cmp_data_type data_type, enum cmp_mode cm cfg_valid = cmp_cfg_icu_gen_par_is_valid(&cfg); if (!cfg_valid) - cfg.data_type = DATA_TYPE_UNKOWN; + cfg.data_type = DATA_TYPE_UNKNOWN; return cfg; } /** - * @brief setup of the different data buffers for an ICU compression + * @brief setup the different data buffers for an ICU compression * * @param cfg pointer to a compression configuration (created * with the cmp_cfg_icu_create() function) * @param data_to_compress pointer to the data to be compressed * @param data_samples length of the data to be compressed measured in - * data samples/entitys (multi entity header not + * data samples/entitys (collection header not * included by imagette data) * @param model_of_data pointer to model data buffer (can be NULL if no * model compression mode is used) @@ -142,7 +146,7 @@ size_t cmp_cfg_icu_buffers(struct cmp_cfg *cfg, void *data_to_compress, * @brief set up the configuration parameters for an ICU imagette compression * * @param cfg pointer to a compression configuration (created - * with the cmp_cfg_icu_create() function) + * by the cmp_cfg_icu_create() function) * @param cmp_par imagette compression parameter (Golomb parameter) * @param spillover_par imagette spillover threshold parameter * @@ -166,11 +170,11 @@ int cmp_cfg_icu_imagette(struct cmp_cfg *cfg, uint32_t cmp_par, /** - * @brief set up of the configuration parameters for a flux/COB compression + * @brief set up the configuration parameters for a flux/COB compression * @note not all parameters are needed for every flux/COB compression data type * * @param cfg pointer to a compression configuration (created - * with the cmp_cfg_icu_create() function) + * by the cmp_cfg_icu_create() function) * @param cmp_par_exp_flags exposure flags compression parameter * @param spillover_exp_flags exposure flags spillover threshold parameter * @param cmp_par_fx normal flux compression parameter @@ -220,13 +224,13 @@ int cmp_cfg_fx_cob(struct cmp_cfg *cfg, /** - * @brief set up of the configuration parameters for an auxiliary science data compression + * @brief set up the configuration parameters for an auxiliary science data compression * @note auxiliary compression data types are: DATA_TYPE_OFFSET, DATA_TYPE_BACKGROUND, DATA_TYPE_SMEARING, DATA_TYPE_F_CAM_OFFSET, DATA_TYPE_F_CAM_BACKGROUND - * @note not all parameters are needed for the every auxiliary compression data types + * @note not all parameters are needed for the every auxiliary compression data type * - * @param cfg pointer to a compression configuration ( - * created with the cmp_cfg_icu_create() function) + * @param cfg pointer to a compression configuration (created + * with the cmp_cfg_icu_create() function) * @param cmp_par_mean mean compression parameter * @param spillover_mean mean spillover threshold parameter * @param cmp_par_variance variance compression parameter @@ -739,29 +743,41 @@ static int configure_encoder_setup(struct encoder_setupt *setup, if (!cfg) return -1; - setup->encoder_par1 = cmp_par; - setup->spillover_par = spillover; if (max_data_bits > 32) { debug_print("Error: max_data_bits parameter is bigger than 32 bits.\n"); return -1; } + + memset(setup, 0, sizeof(*setup)); + + setup->encoder_par1 = cmp_par; setup->max_data_bits = max_data_bits; setup->lossy_par = lossy_par; + setup->bitstream_adr = cfg->icu_output_buf; + setup->max_stream_len = cmp_buffer_length_to_bits(cfg->buffer_length, cfg->data_type); + + if (cfg->cmp_mode != CMP_MODE_STUFF) { + if (ilog_2(cmp_par) < 0) + return -1; + setup->encoder_par2 = (uint32_t)ilog_2(cmp_par); + + setup->spillover_par = spillover; + + /* for encoder_par1 which are a power of two we can use the faster rice_encoder */ + if (is_a_pow_of_2(setup->encoder_par1)) + setup->generate_cw_f = &rice_encoder; + else + setup->generate_cw_f = &golomb_encoder; + } switch (cfg->cmp_mode) { case CMP_MODE_MODEL_ZERO: case CMP_MODE_DIFF_ZERO: setup->encode_method_f = &encode_value_zero; - if (ilog_2(cmp_par) < 0) - return -1; - setup->encoder_par2 = (uint32_t)ilog_2(cmp_par); break; case CMP_MODE_MODEL_MULTI: case CMP_MODE_DIFF_MULTI: setup->encode_method_f = &encode_value_multi; - if (ilog_2(cmp_par) < 0) - return -1; - setup->encoder_par2 = (uint32_t)ilog_2(cmp_par); break; case CMP_MODE_STUFF: setup->encode_method_f = &encode_value_none; @@ -771,14 +787,6 @@ static int configure_encoder_setup(struct encoder_setupt *setup, return -1; } - /* for encoder_par1 which are a power of two we can use the faster rice_encoder */ - if (is_a_pow_of_2(setup->encoder_par1)) - setup->generate_cw_f = &rice_encoder; - else - setup->generate_cw_f = &golomb_encoder; - - setup->bitstream_adr = cfg->icu_output_buf; - setup->max_stream_len = cmp_buffer_length_to_bits(cfg->buffer_length, cfg->data_type); return 0; } @@ -808,9 +816,6 @@ static int compress_imagette(const struct cmp_cfg *cfg) uint16_t *next_model_p = data_buf; uint16_t *up_model_buf = NULL; - if (cfg->samples == 0) - return 0; - if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; next_model_p = &model_buf[1]; @@ -843,10 +848,10 @@ static int compress_imagette(const struct cmp_cfg *cfg) * @brief compress the multi-entry packet header structure and sets the data, * model and up_model pointers to the data after the header * - * @param data pointer to a pointer pointing to the data to be compressed - * @param model pointer to a pointer pointing to the model of the data - * @param up_model pointer to a pointer pointing to the updated model buffer - * @param cfg pointer to the compression configuration structure + * @param data pointer to a pointer pointing to the data to be compressed + * @param model pointer to a pointer pointing to the model of the data + * @param up_model pointer to a pointer pointing to the updated model buffer + * @param compressed_data pointer to the compressed data buffer * * @returns the bit length of the bitstream on success; negative on error, * @@ -855,26 +860,23 @@ static int compress_imagette(const struct cmp_cfg *cfg) */ static int compress_multi_entry_hdr(void **data, void **model, void **up_model, - const struct cmp_cfg *cfg) + void *compressed_data) { - if (cfg->buffer_length < 1) - return -1; + if (*up_model) { + if (*data) + memcpy(*up_model, *data, MULTI_ENTRY_HDR_SIZE); + *up_model = (uint8_t *)*up_model + MULTI_ENTRY_HDR_SIZE; + } if (*data) { - if (cfg->icu_output_buf) - memcpy(cfg->icu_output_buf, *data, MULTI_ENTRY_HDR_SIZE); + if (compressed_data) + memcpy(compressed_data, *data, MULTI_ENTRY_HDR_SIZE); *data = (uint8_t *)*data + MULTI_ENTRY_HDR_SIZE; } if (*model) *model = (uint8_t *)*model + MULTI_ENTRY_HDR_SIZE; - if (*up_model) { - if (*data) - memcpy(*up_model, *data, MULTI_ENTRY_HDR_SIZE); - *up_model = (uint8_t *)*up_model + MULTI_ENTRY_HDR_SIZE; - } - return MULTI_ENTRY_HDR_SIZE * CHAR_BIT; } @@ -906,7 +908,7 @@ static int compress_s_fx(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -978,7 +980,7 @@ static int compress_s_fx_efx(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1060,7 +1062,7 @@ static int compress_s_fx_ncob(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1149,7 +1151,7 @@ static int compress_s_fx_efx_ncob_ecob(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1263,7 +1265,7 @@ static int compress_f_fx(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1325,7 +1327,7 @@ static int compress_f_fx_efx(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1397,7 +1399,7 @@ static int compress_f_fx_ncob(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1475,7 +1477,7 @@ static int compress_f_fx_efx_ncob_ecob(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1579,7 +1581,7 @@ static int compress_l_fx(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1661,7 +1663,7 @@ static int compress_l_fx_efx(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1754,7 +1756,7 @@ static int compress_l_fx_ncob(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1870,7 +1872,7 @@ static int compress_l_fx_efx_ncob_ecob(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -2010,7 +2012,7 @@ static int compress_nc_offset(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -2081,7 +2083,7 @@ static int compress_nc_background(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -2163,7 +2165,7 @@ static int compress_smearing(const struct cmp_cfg *cfg) up_model_buf = cfg->icu_new_model_buf; stream_len = compress_multi_entry_hdr((void **)&data_buf, (void **)&model_buf, - (void **)&up_model_buf, cfg); + (void **)&up_model_buf, cfg->icu_output_buf); if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -2236,13 +2238,13 @@ static int pad_bitstream(const struct cmp_cfg *cfg, int cmp_size) if (cmp_size < 0) return cmp_size; - /* maximum length of the bitstream/icu_output_buf in bits */ - output_buf_len_bits = cmp_buffer_length_to_bits(cfg->buffer_length, cfg->data_type); - - /* no padding in RAW mode*/ + /* no padding in RAW mode; DIFFERENCE ENDIANNESS */ if (cfg->cmp_mode == CMP_MODE_RAW) return cmp_size; + /* maximum length of the bitstream/icu_output_buf in bits */ + output_buf_len_bits = cmp_buffer_length_to_bits(cfg->buffer_length, cfg->data_type); + n_pad_bits = 32 - ((unsigned int)cmp_size & 0x1FU); if (n_pad_bits < 32) { int n_bits = put_n_bits32(0, n_pad_bits, cmp_size, cfg->icu_output_buf, @@ -2264,37 +2266,41 @@ static int pad_bitstream(const struct cmp_cfg *cfg, int cmp_size) * @returns 0 on success; non-zero on failure */ -static int cmp_data_to_big_endian(const struct cmp_cfg *cfg, unsigned int cmp_size) +static int cmp_data_to_big_endian(const struct cmp_cfg *cfg, int cmp_size) { #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) size_t i; uint32_t *p; + uint32_t s = (uint32_t)cmp_size; - if (cfg->cmp_mode == CMP_MODE_RAW) { - int err = cmp_input_big_to_cpu_endianness(cfg->icu_output_buf, - cmp_size/CHAR_BIT, cfg->data_type); - return err; - } + if (cmp_size < 0) + return cmp_size; - if (rdcu_supported_data_type_is_used(cfg->data_type)) { - p = cfg->icu_output_buf; + if (cfg->cmp_mode == CMP_MODE_RAW) { + if (cmp_input_big_to_cpu_endianness(cfg->icu_output_buf, + s/CHAR_BIT, cfg->data_type)) + cmp_size = -1; } else { - p = &cfg->icu_output_buf[MULTI_ENTRY_HDR_SIZE/sizeof(uint32_t)]; - cmp_size -= MULTI_ENTRY_HDR_SIZE * CHAR_BIT; - } + if (rdcu_supported_data_type_is_used(cfg->data_type)) { + p = cfg->icu_output_buf; + } else { + p = &cfg->icu_output_buf[MULTI_ENTRY_HDR_SIZE/sizeof(uint32_t)]; + s -= MULTI_ENTRY_HDR_SIZE * CHAR_BIT; + } - for (i = 0; i < cmp_bit_to_4byte(cmp_size)/sizeof(uint32_t); i++) - cpu_to_be32s(&p[i]); + for (i = 0; i < cmp_bit_to_4byte(s)/sizeof(uint32_t); i++) + cpu_to_be32s(&p[i]); + } #else /* do nothing data are already in big-endian */ (void)cfg; #endif /*__BYTE_ORDER__ */ - return 0; + return cmp_size; } /** - * @brief compress data on the ICU + * @brief compress data on the ICU in software * * @param cfg pointer to a compression configuration (created with the * cmp_cfg_icu_create() function, setup with the cmp_cfg_xxx() functions) @@ -2319,22 +2325,22 @@ int icu_compress_data(const struct cmp_cfg *cfg) if (cfg->samples == 0) /* nothing to compress we are done*/ return 0; - if (!cmp_cfg_is_valid(cfg)) - return -1; + if (raw_mode_is_used(cfg->cmp_mode)) + if (cfg->samples > cfg->buffer_length) + return CMP_ERROR_SAMLL_BUF; - if (model_mode_is_used(cfg->cmp_mode) && !cfg->model_buf) + if (!cmp_cfg_is_valid(cfg)) return -1; if (raw_mode_is_used(cfg->cmp_mode)) { - if (cfg->samples > cfg->buffer_length) { - cmp_size = CMP_ERROR_SAMLL_BUF; - } else { - cmp_size = cmp_cal_size_of_data(cfg->samples, cfg->data_type); - if (cfg->icu_output_buf) - memcpy(cfg->icu_output_buf, cfg->input_buf, cmp_size); - cmp_size *= CHAR_BIT; /* convert to bits */ - } + cmp_size = cmp_cal_size_of_data(cfg->samples, cfg->data_type); + if (cfg->icu_output_buf) + memcpy(cfg->icu_output_buf, cfg->input_buf, cmp_size); + cmp_size *= CHAR_BIT; /* convert to bits */ } else { + if (cfg->samples < cfg->buffer_length/3) + debug_print("Warning: The size of the compressed_data buffer is 3 times smaller than the data_to_compress. This is probably unintended.\n"); + switch (cfg->data_type) { case DATA_TYPE_IMAGETTE: case DATA_TYPE_IMAGETTE_ADAPTIVE: @@ -2396,16 +2402,16 @@ int icu_compress_data(const struct cmp_cfg *cfg) case DATA_TYPE_F_CAM_OFFSET: case DATA_TYPE_F_CAM_BACKGROUND: - case DATA_TYPE_UNKOWN: + case DATA_TYPE_UNKNOWN: default: debug_print("Error: Data type not supported.\n"); cmp_size = -1; } } - if (cfg->icu_output_buf && cmp_size > 0) { + if (cfg->icu_output_buf) { cmp_size = pad_bitstream(cfg, cmp_size); - cmp_data_to_big_endian(cfg, (unsigned int)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 ff4eb6c..c3ffb7c 100644 --- a/lib/cmp_rdcu.c +++ b/lib/cmp_rdcu.c @@ -133,13 +133,13 @@ static int rdcu_cfg_gen_par_is_invalid(const struct cmp_cfg *cfg) /** * @brief create an RDCU compression configuration * - * @param data_type compression data product types + * @param data_type compression data product type * @param cmp_mode compression mode - * @param model_value model weighting parameter (only need for model compression mode) + * @param model_value model weighting parameter (only needed for model compression mode) * @param lossy_par lossy rounding parameter (use CMP_LOSSLESS for lossless compression) * - * @returns compression configuration containing the chosen parameters; - * on error the data_type record is set to DATA_TYPE_UNKOWN + * @returns a compression configuration containing the chosen parameters; + * on error the data_type record is set to DATA_TYPE_UNKNOWN */ struct cmp_cfg rdcu_cfg_create(enum cmp_data_type data_type, enum cmp_mode cmp_mode, @@ -155,7 +155,7 @@ struct cmp_cfg rdcu_cfg_create(enum cmp_data_type data_type, enum cmp_mode cmp_m cfg.round = lossy_par; if (rdcu_cfg_gen_par_is_invalid(&cfg)) - cfg.data_type = DATA_TYPE_UNKOWN; + cfg.data_type = DATA_TYPE_UNKNOWN; return cfg; } @@ -348,27 +348,26 @@ static int rdcu_cfg_buffers_is_invalid(const struct cmp_cfg *cfg) /** - *@brief setup of the different data buffers for an RDCU compression + * @brief setup of the different data buffers for an RDCU compression * * @param cfg pointer to a compression configuration (created * with the rdcu_cfg_create() function) * @param data_to_compress pointer to the data to be compressed (if NULL no * data transfer to the RDCU) * @param data_samples length of the data to be compressed measured in - * 16-bit data samples (ignoring the multi entity header) + * 16-bit data samples (ignoring the collection header) * @param model_of_data pointer to model data buffer (only needed for * model compression mode, if NULL no model data * transfer to the RDCU) - * @param rdcu_data_adr RDCU data to compress start address, the first - * data address in the RDCU SRAM - * @param rdcu_model_adr RDCU model start address, the first model address - * in the RDCU SRAM (only need for model compression mode) - * @param rdcu_new_model_adr RDCU new/updated model start address(can be the + * @param rdcu_data_adr RDCU SRAM data to compress start address + * @param rdcu_model_adr RDCU SRAM model start address (only need for + * model compression mode) + * @param rdcu_new_model_adr RDCU SRAM new/updated model start address(can be the * by the same as rdcu_model_adr for in-place model update) - * @param rdcu_buffer_adr RDCU compressed data start address, the first - * output data address in the RDCU SRAM + * @param rdcu_buffer_adr RDCU SRAM compressed data start address * @param rdcu_buffer_lenght length of the RDCU compressed data SRAM buffer - * in number of 16-bit samples + * measured in 16-bit units (same as data_samples) + * * @returns 0 if parameters are valid, non-zero if parameters are invalid */ @@ -441,9 +440,9 @@ static int rdcu_cfg_imagette_is_invalid(const struct cmp_cfg *cfg) cfg_invalid++; } - if (cfg->spill > get_max_spill(cfg->golomb_par, cfg->data_type)) { + if (cfg->spill > cmp_rdcu_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, get_max_spill(cfg->golomb_par, cfg->data_type)); + cfg->spill, cfg->golomb_par, cmp_rdcu_max_spill(cfg->golomb_par)); cfg_invalid++; } @@ -453,9 +452,9 @@ static int rdcu_cfg_imagette_is_invalid(const struct cmp_cfg *cfg) cfg_invalid++; } - if (cfg->ap1_spill > get_max_spill(cfg->ap1_golomb_par, cfg->data_type)) { + if (cfg->ap1_spill > cmp_rdcu_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, get_max_spill(cfg->ap1_golomb_par, cfg->data_type)); + cfg->ap1_spill, cfg->ap1_golomb_par, cmp_rdcu_max_spill(cfg->ap1_golomb_par)); cfg_invalid++; } @@ -465,9 +464,9 @@ static int rdcu_cfg_imagette_is_invalid(const struct cmp_cfg *cfg) cfg_invalid++; } - if (cfg->ap2_spill > get_max_spill(cfg->ap2_golomb_par, cfg->data_type)) { + if (cfg->ap2_spill > cmp_rdcu_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, get_max_spill(cfg->ap2_golomb_par, cfg->data_type)); + cfg->ap2_spill, cfg->ap2_golomb_par, cmp_rdcu_max_spill(cfg->ap2_golomb_par)); cfg_invalid++; } @@ -484,12 +483,12 @@ static int rdcu_cfg_imagette_is_invalid(const struct cmp_cfg *cfg) * * @param cfg pointer to a compression configuration (created * with the rdcu_cfg_create() function) - * @param golomb_par imagette compression parameter (Golomb parameter) + * @param golomb_par imagette compression parameter * @param spillover_par imagette spillover threshold parameter - * @param ap1_golomb_par adaptive 1 imagette compression parameter (ap1_golomb parameter) + * @param ap1_golomb_par adaptive 1 imagette compression parameter * @param ap1_spillover_par adaptive 1 imagette spillover threshold parameter - * @param ap2_golomb_par adaptive 2 imagette compression parameter (ap2_golomb parameter) - * @param ap2_spillover_par adaptive 1 imagette spillover threshold parameter + * @param ap2_golomb_par adaptive 2 imagette compression parameter + * @param ap2_spillover_par adaptive 2 imagette spillover threshold parameter * * @returns 0 if parameters are valid, non-zero if parameters are invalid */ @@ -677,11 +676,9 @@ int rdcu_start_compression(void) * * @param cfg configuration contains all parameters required for compression * - * @note Before the rdcu_compress function can be used, an initialization of + * @note Before the rdcu_compress function can be used, an initialisation of * the RMAP library is required. This is achieved with the functions * rdcu_ctrl_init() and rdcu_rmap_init(). - * @note When using the 1d-differencing mode or the raw mode (cmp_mode = 0,2,4), - * the model parameters (model_value, model_of_data, rdcu_model_adr) are ignored. * @note The validity of the cfg structure is checked before the compression is * started. * diff --git a/lib/cmp_support.c b/lib/cmp_support.c index 666ce96..cfa7dc5 100644 --- a/lib/cmp_support.c +++ b/lib/cmp_support.c @@ -67,7 +67,12 @@ int is_a_pow_of_2(unsigned int v) int cmp_data_type_valid(enum cmp_data_type data_type) { - if (data_type <= DATA_TYPE_UNKOWN || data_type > DATA_TYPE_F_CAM_OFFSET) + if (data_type == DATA_TYPE_F_CAM_OFFSET) + debug_print("Error: DATA_TYPE_F_CAM_OFFSET is TBD and not implemented yet.\n"); + if (data_type == DATA_TYPE_F_CAM_BACKGROUND) + debug_print("Error: DATA_TYPE_F_CAM_BACKGROUND is TBD and not implemented yet.\n"); + + if (data_type <= DATA_TYPE_UNKNOWN || data_type > DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE) return 0; return 1; @@ -154,7 +159,7 @@ int rdcu_supported_cmp_mode_is_used(enum cmp_mode cmp_mode) /** * @brief check if the data product data type is supported by the RDCU compressor * - * @param data_type compression data product types + * @param data_type compression data product type * * @returns 1 when the data type is supported by the RDCU, otherwise 0 */ @@ -393,16 +398,18 @@ unsigned int cmp_up_model(unsigned int data, unsigned int model, /** - * @brief get the maximum valid spill threshold value for a given golomb_par + * @brief get the maximum valid spill threshold value for a RDCU HW compression + * in diff or model mode * * @param golomb_par Golomb parameter - * @param data_type compression data type * - * @returns the highest still valid spill threshold value + * @returns the highest still valid spill threshold value for a diff of model + * mode compression; 0 if golomb_par is invalid */ -uint32_t get_max_spill(unsigned int golomb_par, enum cmp_data_type data_type) +uint32_t cmp_rdcu_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, 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, @@ -410,30 +417,36 @@ uint32_t get_max_spill(unsigned int golomb_par, enum cmp_data_type data_type) 452, 461, 470, 479, 488, 497, 506, 515, 524, 533, 542, 551, 560, 569, 578, 587, 596, 605, 614, 623 }; - if (golomb_par == 0) + + if (golomb_par > MAX_RDCU_GOLOMB_PAR) return 0; - /* the RDCU can only generate 16 bit long code words -> lower max spill needed */ - if (rdcu_supported_data_type_is_used(data_type)) { - if (golomb_par > MAX_RDCU_GOLOMB_PAR) - return 0; + return LUT_MAX_RDCU[golomb_par]; +} - return LUT_MAX_RDCU[golomb_par]; - } - if (golomb_par > MAX_ICU_GOLOMB_PAR) { +/** + * @brief get the maximum valid spill threshold value for a ICU SW compression + * in diff or model mode + * + * @param cmp_par compression parameter + * + * @returns the highest still valid spill threshold value for diff or model + * mode compression; 0 if the cmp_par is not valid + */ + +uint32_t cmp_icu_max_spill(unsigned int cmp_par) +{ + /* the ICU compressor can generate code words with a length of maximal 32 bits. */ + unsigned int max_cw_bits = 32; + unsigned int cutoff = (1UL << (ilog_2(cmp_par)+1)) - cmp_par; + unsigned int max_n_sym_offset = max_cw_bits/2 - 1; + + if (!cmp_par || cmp_par > MAX_ICU_GOLOMB_PAR) return 0; - } else { - /* the ICU compressor can generate code words with a length of - * maximal 32 bits. - */ - unsigned int max_cw_bits = 32; - unsigned int cutoff = (1UL << (ilog_2(golomb_par)+1)) - golomb_par; - unsigned int max_n_sym_offset = max_cw_bits/2 - 1; - - return (max_cw_bits-1-ilog_2(golomb_par))*golomb_par + cutoff - - max_n_sym_offset - 1; - } + + return (max_cw_bits-1-ilog_2(cmp_par))*cmp_par + cutoff + - max_n_sym_offset - 1; } @@ -465,13 +478,16 @@ int cmp_cfg_icu_gen_par_is_valid(const struct cmp_cfg *cfg) { int cfg_invalid = 0; + if (!cfg) + return 0; + if (!cmp_data_type_valid(cfg->data_type)) { debug_print("Error: selected compression data type is not supported.\n"); cfg_invalid++; } if (cfg->cmp_mode > CMP_MODE_STUFF) { - debug_print("Error: selected cmp_mode: %u is not supported\n.", cfg->cmp_mode); + debug_print("Error: selected cmp_mode: %u is not supported.\n", cfg->cmp_mode); cfg_invalid++; } @@ -519,14 +535,21 @@ int cmp_cfg_icu_buffers_is_valid(const struct cmp_cfg *cfg) if (cfg->samples == 0) debug_print("Warning: The samples parameter is 0. No data are compressed. This behavior may not be intended.\n"); - if (cfg->icu_output_buf && cfg->buffer_length == 0 && cfg->samples != 0) { - debug_print("Error: The buffer_length is set to 0. There is no space to store the compressed data.\n"); - cfg_invalid++; - } + if (cfg->icu_output_buf) { + if (cfg->buffer_length == 0 && cfg->samples != 0) { + debug_print("Error: The buffer_length is set to 0. There is no space to store the compressed data.\n"); + cfg_invalid++; + } - if (cfg->icu_output_buf == cfg->input_buf) { - debug_print("Error: The compressed_data buffer is the same as the data_to_compress buffer.\n"); - cfg_invalid++; + if (raw_mode_is_used(cfg->cmp_mode) && cfg->buffer_length < cfg->samples) { + debug_print("Error: The compressed_data_len_samples is to small to hold the data form the data_to_compress.\n"); + cfg_invalid++; + } + + if (cfg->icu_output_buf == cfg->input_buf) { + debug_print("Error: The compressed_data buffer is the same as the data_to_compress buffer.\n"); + cfg_invalid++; + } } if (model_mode_is_used(cfg->cmp_mode)) { @@ -558,16 +581,6 @@ int cmp_cfg_icu_buffers_is_valid(const struct cmp_cfg *cfg) } } - if (raw_mode_is_used(cfg->cmp_mode)) { - if (cfg->buffer_length < cfg->samples) { - debug_print("Error: The compressed_data_len_samples is to small to hold the data form the data_to_compress.\n"); - cfg_invalid++; - } - } else { - if (cfg->samples < cfg->buffer_length/3) - debug_print("Warning: The size of the compressed_data buffer is 3 times smaller than the data_to_compress. This is probably unintended.This is probably unintended.\n"); - } - if (cfg_invalid) return 0; @@ -589,7 +602,7 @@ int cmp_cfg_icu_buffers_is_valid(const struct cmp_cfg *cfg) */ static int cmp_pars_are_valid(uint32_t cmp_par, uint32_t spill, enum cmp_mode cmp_mode, - enum cmp_data_type data_type, char *par_name) + char *par_name) { int cfg_invalid = 0; @@ -622,9 +635,9 @@ static int cmp_pars_are_valid(uint32_t cmp_par, uint32_t spill, enum cmp_mode cm par_name, spill, MIN_ICU_SPILL); cfg_invalid++; } - if (spill > get_max_spill(cmp_par, data_type)) { + if (spill > cmp_icu_max_spill(cmp_par)) { 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, get_max_spill(cmp_par, data_type)); + par_name, spill, par_name, cmp_par, cmp_icu_max_spill(cmp_par)); cfg_invalid++; } @@ -658,20 +671,20 @@ int cmp_cfg_imagette_is_valid(const struct cmp_cfg *cfg) return 0; if (!cmp_imagette_data_type_is_used(cfg->data_type)) { - debug_print("Error: The compression data type is not an imagette compression data type.!\n"); + debug_print("Error: The compression data type is not an imagette compression data type!\n"); cfg_invalid++; } if (!cmp_pars_are_valid(cfg->golomb_par, cfg->spill, cfg->cmp_mode, - cfg->data_type, "imagette")) + "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, cfg->data_type, "adaptive 1 imagette")) + cfg->cmp_mode, "adaptive 1 imagette")) cfg_invalid++; if (!cmp_pars_are_valid(cfg->ap2_golomb_par, cfg->ap2_spill, - cfg->cmp_mode, cfg->data_type, "adaptive 2 imagette")) + cfg->cmp_mode, "adaptive 2 imagette")) cfg_invalid++; } @@ -703,7 +716,7 @@ 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, cfg->data_type, "flux")) + if (!cmp_pars_are_valid(cfg->cmp_par_fx, cfg->spill_fx, cfg->cmp_mode, "flux")) cfg_invalid++; switch (cfg->data_type) { @@ -763,15 +776,20 @@ 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, cfg->data_type, "exposure flags")) + 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, cfg->data_type, "center of brightness")) + 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, cfg->data_type, "extended flux")) + 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, cfg->data_type, "extended center of brightness")) + 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, cfg->data_type, "flux COB varianc")) + 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) @@ -787,6 +805,7 @@ int cmp_cfg_fx_cob_is_valid(const struct cmp_cfg *cfg) * @param cfg pointer to the compressor configuration * * @returns 1 if the auxiliary science specific parameters are valid, otherwise 0 + * TODO: implemented DATA_TYPE_F_CAM_OFFSET and DATA_TYPE_F_CAM_BACKGROUND */ int cmp_cfg_aux_is_valid(const struct cmp_cfg *cfg) @@ -801,12 +820,16 @@ 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, cfg->data_type, "mean")) + 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, cfg->data_type, "variance")) + if (!cmp_pars_are_valid(cfg->cmp_par_variance, cfg->spill_variance, + cfg->cmp_mode, "variance")) cfg_invalid++; - if (cfg->data_type != DATA_TYPE_OFFSET && cfg->data_type != DATA_TYPE_F_CAM_OFFSET) - if (!cmp_pars_are_valid(cfg->cmp_par_pixels_error, cfg->spill_pixels_error, cfg->cmp_mode, cfg->data_type, "outlier pixls num")) + /* 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) diff --git a/test/cmp_icu/test_cmp_icu.c b/test/cmp_icu/test_cmp_icu.c index 35f938a..d2c46ce 100644 --- a/test/cmp_icu/test_cmp_icu.c +++ b/test/cmp_icu/test_cmp_icu.c @@ -1,11 +1,1151 @@ +#include "cmp_support.h" #include <string.h> #include <stdlib.h> +#if defined __has_include +# if __has_include(<time.h>) +# include <time.h> +# include <unistd.h> +# define HAS_TIME_H 1 +# endif +#endif #include "unity.h" +#include "cmp_icu.h" +#include "../lib/cmp_icu.c" /* this is a hack to test static functions */ -#include "cmp_support.h" -/* this is a hack to test static functions */ -#include "../lib/cmp_icu.c" +/* TODO: test compression with samples = 0 and buffer_length = 0; */ + +/** + * @brief Seeds the pseudo-random number generator used by rand() + */ + +void setUp(void) +{ + unsigned int seed; + static int n; + +#if HAS_TIME_H + seed = time(NULL) * getpid(); +#else + seed = 1; +#endif + + if (!n) { + n++; + srand(seed); + printf("seed: %u\n", seed); + } +} + + +/** + * @brief generate a random number + * + * @param min minimum value + * @param max maximum value + * + * @returns "random" numbers in the range [M, N] + * + * @see https://c-faq.com/lib/randrange.html + */ + +int random_range(unsigned int min, unsigned int max) +{ + if (min > max) + TEST_ASSERT(0); + if (max-min > RAND_MAX) + TEST_ASSERT(0); + return min + rand() / (RAND_MAX / (max - min + 1) + 1); +} + + +/** + * @test cmp_cfg_icu_create + */ + +void test_cmp_cfg_icu_create(void) +{ + struct cmp_cfg cfg; + enum cmp_data_type data_type; + enum cmp_mode cmp_mode; + uint32_t model_value, lossy_par; + /* TODO: change that when DATA_TYPE_BACKGROUND and + * DATA_TYPE_F_CAM_BACKGROUND are implemented */ + const enum cmp_data_type biggest_data_type = DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE; + + /* wrong data type tests */ + data_type = DATA_TYPE_UNKNOWN; /* not valid data type */ + cmp_mode = CMP_MODE_RAW; + model_value = 0; + lossy_par = CMP_LOSSLESS; + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_UNKNOWN, cfg.data_type); + memset(&cfg, 0, sizeof(cfg)); + + data_type = biggest_data_type + 1; /* not valid data type */ + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_UNKNOWN, cfg.data_type); + memset(&cfg, 0, sizeof(cfg)); + + data_type = biggest_data_type; + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(biggest_data_type, cfg.data_type); + TEST_ASSERT_EQUAL_INT(CMP_MODE_RAW, cfg.cmp_mode); + TEST_ASSERT_EQUAL_INT(0, cfg.model_value); + TEST_ASSERT_EQUAL_INT(0, cfg.round); + memset(&cfg, 0, sizeof(cfg)); + + /* this should work */ + data_type = DATA_TYPE_IMAGETTE; + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_IMAGETTE, cfg.data_type); + TEST_ASSERT_EQUAL_INT(CMP_MODE_RAW, cfg.cmp_mode); + TEST_ASSERT_EQUAL_INT(0, cfg.model_value); + TEST_ASSERT_EQUAL_INT(0, cfg.round); + memset(&cfg, 0, sizeof(cfg)); + + /* wrong compression mode tests */ + cmp_mode = CMP_MODE_STUFF + 1; + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_UNKNOWN, cfg.data_type); + memset(&cfg, 0, sizeof(cfg)); + + cmp_mode = -1; + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_UNKNOWN, cfg.data_type); + memset(&cfg, 0, sizeof(cfg)); + + /* this should work */ + cmp_mode = CMP_MODE_STUFF; + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_IMAGETTE, cfg.data_type); + TEST_ASSERT_EQUAL_INT(CMP_MODE_STUFF, cfg.cmp_mode); + TEST_ASSERT_EQUAL_INT(0, cfg.model_value); + TEST_ASSERT_EQUAL_INT(0, cfg.round); + memset(&cfg, 0, sizeof(cfg)); + + /* wrong model_value tests */ + cmp_mode = CMP_MODE_MODEL_MULTI; /* model value checks only active on model mode */ + model_value = MAX_MODEL_VALUE + 1; + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_UNKNOWN, cfg.data_type); + + model_value = -1U; + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_UNKNOWN, cfg.data_type); + + /* this should work */ + model_value = MAX_MODEL_VALUE; + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_IMAGETTE, cfg.data_type); + TEST_ASSERT_EQUAL_INT(CMP_MODE_MODEL_MULTI, cfg.cmp_mode); + TEST_ASSERT_EQUAL_INT(16, cfg.model_value); + TEST_ASSERT_EQUAL_INT(0, cfg.round); + + /* no checks for model mode -> no model cmp_mode */ + cmp_mode = CMP_MODE_STUFF; + model_value = MAX_MODEL_VALUE + 1; + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_IMAGETTE, cfg.data_type); + TEST_ASSERT_EQUAL_INT(CMP_MODE_STUFF, cfg.cmp_mode); + TEST_ASSERT_EQUAL_INT(MAX_MODEL_VALUE + 1, cfg.model_value); + TEST_ASSERT_EQUAL_INT(0, cfg.round); + model_value = MAX_MODEL_VALUE; + + /* wrong lossy_par tests */ + lossy_par = MAX_ICU_ROUND + 1; + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_UNKNOWN, cfg.data_type); + + lossy_par = -1U; + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_UNKNOWN, cfg.data_type); + + /* this should work */ + lossy_par = MAX_ICU_ROUND; + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_IMAGETTE, cfg.data_type); + TEST_ASSERT_EQUAL_INT(CMP_MODE_STUFF, cfg.cmp_mode); + TEST_ASSERT_EQUAL_INT(16, cfg.model_value); + TEST_ASSERT_EQUAL_INT(3, cfg.round); + + /* random test */ + data_type = random_range(DATA_TYPE_IMAGETTE, biggest_data_type); + cmp_mode = random_range(CMP_MODE_RAW, CMP_MODE_STUFF); + model_value = random_range(0, MAX_MODEL_VALUE); + lossy_par = random_range(CMP_LOSSLESS, MAX_ICU_ROUND); + cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); + TEST_ASSERT_EQUAL_INT(data_type, cfg.data_type); + TEST_ASSERT_EQUAL_INT(cmp_mode, cfg.cmp_mode); + TEST_ASSERT_EQUAL_INT(model_value, cfg.model_value); + TEST_ASSERT_EQUAL_INT(lossy_par, cfg.round); +} + + +/** + * @test cmp_cfg_icu_buffers + */ + +void test_cmp_cfg_icu_buffers(void) +{ + struct cmp_cfg cfg; + void *data_to_compress; + uint32_t data_samples; + void *model_of_data; + void *updated_model; + uint32_t *compressed_data; + uint32_t compressed_data_len_samples; + size_t s; + uint16_t ima_data[4] = {42, 23, 0, 0xFFFF}; + uint16_t ima_model[4] = {0xC, 0xA, 0xFF, 0xE}; + uint16_t ima_up_model[4] = {0}; + uint32_t cmp_data[2] = {0}; + + /* error case: unknown data_type */ + cfg = cmp_cfg_icu_create(DATA_TYPE_UNKNOWN, CMP_MODE_DIFF_ZERO, 16, CMP_LOSSLESS); + data_to_compress = ima_data; + data_samples = 4; + model_of_data = NULL; + updated_model = NULL; + compressed_data = cmp_data; + compressed_data_len_samples = 4; + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(0, s); + + /* error case: no data test */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_DIFF_ZERO, 16, CMP_LOSSLESS); + data_to_compress = NULL; /* no data set */ + data_samples = 4; + model_of_data = NULL; + updated_model = NULL; + compressed_data = cmp_data; + compressed_data_len_samples = 4; + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(0, s); + + /* now its should work */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_DIFF_ZERO, 16, CMP_LOSSLESS); + data_to_compress = ima_data; + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(8, s); + TEST_ASSERT_EQUAL(ima_data, cfg.input_buf); + TEST_ASSERT_EQUAL_INT(NULL, cfg.model_buf); + TEST_ASSERT_EQUAL_INT(4, cfg.samples); + TEST_ASSERT_EQUAL(NULL, cfg.icu_new_model_buf); + TEST_ASSERT_EQUAL(cmp_data, cfg.icu_output_buf); + TEST_ASSERT_EQUAL_INT(4, cfg.buffer_length); + + /* error case: model mode and no model */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_ZERO, 16, CMP_LOSSLESS); + model_of_data = NULL; + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(0, s); + + /* now its should work */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_ZERO, 16, CMP_LOSSLESS); + model_of_data = ima_model; + updated_model = ima_model; + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(8, s); + TEST_ASSERT_EQUAL(ima_data, cfg.input_buf); + TEST_ASSERT_EQUAL_INT(ima_model, cfg.model_buf); + TEST_ASSERT_EQUAL_INT(4, cfg.samples); + TEST_ASSERT_EQUAL(ima_model, cfg.icu_new_model_buf); + TEST_ASSERT_EQUAL(cmp_data, cfg.icu_output_buf); + TEST_ASSERT_EQUAL_INT(4, cfg.buffer_length); + + /* error case: data == model */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_ZERO, 16, CMP_LOSSLESS); + data_to_compress = ima_data; + model_of_data = ima_data; + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(0, s); + + /* error case: data == compressed_data */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_ZERO, 16, CMP_LOSSLESS); + data_to_compress = ima_data; + model_of_data = ima_model; + compressed_data = (void *)ima_data; + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(0, s); + + /* error case: data == updated_model */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_ZERO, 16, CMP_LOSSLESS); + data_to_compress = ima_data; + model_of_data = ima_model; + updated_model = ima_data; + compressed_data = (void *)ima_data; + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(0, s); + + /* error case: model == compressed_data */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_ZERO, 16, CMP_LOSSLESS); + data_to_compress = ima_data; + model_of_data = ima_model; + compressed_data = (void *)ima_model; + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(0, s); + + /* error case: updated_model == compressed_data */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_ZERO, 16, CMP_LOSSLESS); + data_to_compress = ima_data; + model_of_data = ima_model; + updated_model = ima_up_model; + compressed_data = (void *)ima_up_model; + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(0, s); + + /* warning case: samples = 0 */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_ZERO, 16, CMP_LOSSLESS); + data_to_compress = ima_data; + data_samples = 0; + model_of_data = ima_model; + updated_model = ima_up_model; + compressed_data = cmp_data; + compressed_data_len_samples = 4; + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(8, s); + TEST_ASSERT_EQUAL(ima_data, cfg.input_buf); + TEST_ASSERT_EQUAL_INT(ima_model, cfg.model_buf); + TEST_ASSERT_EQUAL_INT(0, cfg.samples); + TEST_ASSERT_EQUAL(ima_up_model, cfg.icu_new_model_buf); + TEST_ASSERT_EQUAL(cmp_data, cfg.icu_output_buf); + TEST_ASSERT_EQUAL_INT(4, cfg.buffer_length); + memset(&cfg, 0, sizeof(cfg)); + + /* error case: compressed_data_len_samples = 0 */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_ZERO, 16, CMP_LOSSLESS); + data_samples = 4; + compressed_data_len_samples = 0; + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(0, s); + + /* this should now work */ + /* if data_samples = 0 -> compressed_data_len_samples = 0 is allowed */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_ZERO, 16, CMP_LOSSLESS); + data_samples = 0; + compressed_data_len_samples = 0; + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(0, s); /* not an error, it is the size of the compressed data */ + TEST_ASSERT_EQUAL(ima_data, cfg.input_buf); + TEST_ASSERT_EQUAL_INT(ima_model, cfg.model_buf); + TEST_ASSERT_EQUAL_INT(0, cfg.samples); + TEST_ASSERT_EQUAL(ima_up_model, cfg.icu_new_model_buf); + TEST_ASSERT_EQUAL(cmp_data, cfg.icu_output_buf); + TEST_ASSERT_EQUAL_INT(0, cfg.buffer_length); + + /* this should now work */ + /* if compressed_data = NULL -> compressed_data_len_samples = 0 is allowed */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_ZERO, 16, CMP_LOSSLESS); + data_samples = 4; + compressed_data = NULL; + compressed_data_len_samples = 0; + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(0, s); /* not an error, it is the size of the compressed data */ + TEST_ASSERT_EQUAL(ima_data, cfg.input_buf); + TEST_ASSERT_EQUAL_INT(ima_model, cfg.model_buf); + TEST_ASSERT_EQUAL_INT(4, cfg.samples); + TEST_ASSERT_EQUAL(ima_up_model, cfg.icu_new_model_buf); + TEST_ASSERT_EQUAL(NULL, cfg.icu_output_buf); + TEST_ASSERT_EQUAL_INT(0, cfg.buffer_length); + + /* error case: RAW mode compressed_data smaller than data_samples */ + compressed_data = cmp_data; + compressed_data_len_samples = 3; + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_RAW, 16, CMP_LOSSLESS); + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(0, s); + + /* this should now work */ + compressed_data = NULL; + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_RAW, 16, CMP_LOSSLESS); + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(6, s); + TEST_ASSERT_EQUAL(ima_data, cfg.input_buf); + TEST_ASSERT_EQUAL_INT(ima_model, cfg.model_buf); + TEST_ASSERT_EQUAL_INT(4, cfg.samples); + TEST_ASSERT_EQUAL(ima_up_model, cfg.icu_new_model_buf); + TEST_ASSERT_EQUAL(NULL, cfg.icu_output_buf); + TEST_ASSERT_EQUAL_INT(3, cfg.buffer_length); + + /* this should also now work */ + compressed_data = cmp_data; + compressed_data_len_samples = 4; + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_RAW, 16, CMP_LOSSLESS); + s = cmp_cfg_icu_buffers(&cfg, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(8, s); + TEST_ASSERT_EQUAL(ima_data, cfg.input_buf); + TEST_ASSERT_EQUAL_INT(ima_model, cfg.model_buf); + TEST_ASSERT_EQUAL_INT(4, cfg.samples); + TEST_ASSERT_EQUAL(ima_up_model, cfg.icu_new_model_buf); + TEST_ASSERT_EQUAL(cmp_data, cfg.icu_output_buf); + TEST_ASSERT_EQUAL_INT(4, cfg.buffer_length); + + /* error case: cfg = NULL */ + s = cmp_cfg_icu_buffers(NULL, data_to_compress, data_samples, + model_of_data, updated_model, compressed_data, + compressed_data_len_samples); + TEST_ASSERT_EQUAL_size_t(0, s); +} + + +/** + * @test cmp_cfg_icu_imagette + */ + +void test_cmp_cfg_icu_imagette(void) +{ + struct cmp_cfg cfg = {0}; + uint32_t cmp_par; + uint32_t spillover_par; + enum cmp_data_type data_type; + + int error; + + /* 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; + error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cfg.golomb_par, 1); + TEST_ASSERT_EQUAL_INT(cfg.spill, 2); + + /* 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); + 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); + + /* wrong data type test */ + for (data_type = 0; data_type <= DATA_TYPE_F_CAM_BACKGROUND; data_type++) { + cfg = cmp_cfg_icu_create(data_type, CMP_MODE_DIFF_MULTI, 16, CMP_LOSSLESS); + error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); + if (data_type == DATA_TYPE_IMAGETTE || + data_type == DATA_TYPE_SAT_IMAGETTE || + 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); + } else { + TEST_ASSERT_TRUE(error); + } + } + + /* model/1d MODE tests */ + + /* 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; + error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); + TEST_ASSERT_TRUE(error); + /* ignore in RAW MODE */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_RAW, 16, CMP_LOSSLESS); + error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); + TEST_ASSERT_FALSE(error); + + /* 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; + error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); + TEST_ASSERT_TRUE(error); + /* ignore in RAW MODE */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_RAW, 16, CMP_LOSSLESS); + error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); + TEST_ASSERT_FALSE(error); + + /* 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; + error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); + TEST_ASSERT_TRUE(error); + /* ignore in RAW MODE */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_RAW, 16, CMP_LOSSLESS); + error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); + TEST_ASSERT_FALSE(error); + + /* 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 ; + error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); + TEST_ASSERT_TRUE(error); + /* ignore in RAW MODE */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_RAW, 16, CMP_LOSSLESS); + error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); + TEST_ASSERT_FALSE(error); + + /* CMP_MODE_STUFF tests */ + spillover_par = ~0; /* is ignored */ + + /* highest values STUFF MODE */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_STUFF, ~0, CMP_LOSSLESS); + cmp_par = MAX_STUFF_CMP_PAR; + error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cfg.golomb_par, 32); + + /* lowest values STUFF MODE */ + cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_STUFF, ~0, CMP_LOSSLESS); + cmp_par = 0; + error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cfg.golomb_par, 0); + + /* cmp_par to big */ + cfg = cmp_cfg_icu_create(DATA_TYPE_SAT_IMAGETTE, CMP_MODE_STUFF, ~0, CMP_LOSSLESS); + cmp_par = MAX_STUFF_CMP_PAR+1; + error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); + TEST_ASSERT_TRUE(error); + + /* cfg = NULL test*/ + error = cmp_cfg_icu_imagette(NULL, cmp_par, spillover_par); + TEST_ASSERT_TRUE(error); + + /* invalid compression mode test*/ + cfg = cmp_cfg_icu_create(DATA_TYPE_SAT_IMAGETTE, CMP_MODE_STUFF+1, ~0, CMP_LOSSLESS); + cmp_par = MAX_STUFF_CMP_PAR+1; + error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); + TEST_ASSERT_TRUE(error); +} + + +/** + * @test cmp_cfg_fx_cob + */ + +void test_cmp_cfg_fx_cob(void) +{ + struct cmp_cfg cfg = {0}; + uint32_t cmp_par_exp_flags = 2; + uint32_t spillover_exp_flags = 2; + uint32_t cmp_par_fx = 2; + uint32_t spillover_fx = 2; + uint32_t cmp_par_ncob = 2; + uint32_t spillover_ncob = 2; + uint32_t cmp_par_efx = 2; + uint32_t spillover_efx = 2; + uint32_t cmp_par_ecob = 2; + uint32_t spillover_ecob = 2; + uint32_t cmp_par_fx_cob_variance = 2; + uint32_t spillover_fx_cob_variance = 2; + int error; + enum cmp_data_type data_type; + + + /* wrong data type test */ + for (data_type = 0; data_type <= DATA_TYPE_F_CAM_BACKGROUND; data_type++) { + cfg = cmp_cfg_icu_create(data_type, CMP_MODE_MODEL_ZERO, 16, CMP_LOSSLESS); + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + if (data_type == DATA_TYPE_S_FX || + data_type == DATA_TYPE_S_FX_DFX || + data_type == DATA_TYPE_S_FX_NCOB || + data_type == DATA_TYPE_S_FX_DFX_NCOB_ECOB || + data_type == DATA_TYPE_L_FX || + data_type == DATA_TYPE_L_FX_DFX || + data_type == DATA_TYPE_L_FX_NCOB || + data_type == DATA_TYPE_L_FX_DFX_NCOB_ECOB || + data_type == DATA_TYPE_F_FX || + data_type == DATA_TYPE_F_FX_DFX || + data_type == DATA_TYPE_F_FX_NCOB || + data_type == DATA_TYPE_F_FX_DFX_NCOB_ECOB) { + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(data_type, cfg.data_type); + TEST_ASSERT_EQUAL_INT(2, cfg.cmp_par_fx); + TEST_ASSERT_EQUAL_INT(2, cfg.spill_fx); + TEST_ASSERT_EQUAL_INT(2, cfg.cmp_par_exp_flags); + TEST_ASSERT_EQUAL_INT(2, cfg.spill_exp_flags); + TEST_ASSERT_EQUAL_INT(2, cfg.cmp_par_efx); + TEST_ASSERT_EQUAL_INT(2, cfg.spill_efx); + TEST_ASSERT_EQUAL_INT(2, cfg.cmp_par_ncob); + TEST_ASSERT_EQUAL_INT(2, cfg.spill_ncob); + TEST_ASSERT_EQUAL_INT(2, cfg.cmp_par_ecob); + TEST_ASSERT_EQUAL_INT(2, cfg.spill_ecob); + TEST_ASSERT_EQUAL_INT(2, cfg.cmp_par_fx_cob_variance); + TEST_ASSERT_EQUAL_INT(2, cfg.spill_fx_cob_variance); + } else { + TEST_ASSERT_TRUE(error); + } + } + + /* cfg == NULL test */ + error = cmp_cfg_fx_cob(NULL, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_TRUE(error); + + /* test DATA_TYPE_S_FX */ + cfg = cmp_cfg_icu_create(DATA_TYPE_S_FX, CMP_MODE_MODEL_ZERO, 16, CMP_LOSSLESS); + cmp_par_exp_flags = MAX_ICU_GOLOMB_PAR; + spillover_exp_flags = cmp_icu_max_spill(cmp_par_exp_flags); + cmp_par_fx = MIN_ICU_GOLOMB_PAR; + spillover_fx = MIN_ICU_SPILL; + cmp_par_ncob = ~0; /* invalid parameter */ + spillover_ncob = ~0; /* invalid parameter */ + cmp_par_efx = ~0; /* invalid parameter */ + spillover_efx = ~0; /* invalid parameter */ + cmp_par_ecob = ~0; /* invalid parameter */ + spillover_ecob = ~0; /* invalid parameter */ + cmp_par_fx_cob_variance = ~0; /* invalid parameter */ + spillover_fx_cob_variance = ~0; /* invalid parameter */ + + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cmp_par_fx, cfg.cmp_par_fx); + TEST_ASSERT_EQUAL_INT(spillover_fx, cfg.spill_fx); + TEST_ASSERT_EQUAL_INT(cmp_par_exp_flags, cfg.cmp_par_exp_flags); + TEST_ASSERT_EQUAL_INT(spillover_exp_flags, cfg.spill_exp_flags); + + /* invalid spillover_exp_flags parameter */ + cmp_par_exp_flags = MAX_ICU_GOLOMB_PAR; + spillover_exp_flags = cmp_icu_max_spill(cmp_par_exp_flags)+1; + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_TRUE(error); + + /* invalid cmp_par_fx parameter */ + cmp_par_exp_flags = MAX_ICU_GOLOMB_PAR; + spillover_exp_flags = cmp_icu_max_spill(cmp_par_exp_flags); + cmp_par_fx = MIN_ICU_GOLOMB_PAR - 1; + spillover_fx = MIN_ICU_SPILL; + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_TRUE(error); + + + /* test DATA_TYPE_S_FX_DFX */ + cfg = cmp_cfg_icu_create(DATA_TYPE_S_FX_DFX, CMP_MODE_MODEL_ZERO, 0, 1); + cmp_par_exp_flags = MAX_ICU_GOLOMB_PAR; + spillover_exp_flags = cmp_icu_max_spill(cmp_par_exp_flags); + cmp_par_fx = MIN_ICU_GOLOMB_PAR; + spillover_fx = MIN_ICU_SPILL; + cmp_par_ncob = ~0; /* invalid parameter */ + spillover_ncob = ~0; /* invalid parameter */ + cmp_par_efx = 23; + spillover_efx = 42; + cmp_par_ecob = ~0; /* invalid parameter */ + spillover_ecob = ~0; /* invalid parameter */ + cmp_par_fx_cob_variance = ~0; /* invalid parameter */ + spillover_fx_cob_variance = ~0; /* invalid parameter */ + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cmp_par_fx, cfg.cmp_par_fx); + TEST_ASSERT_EQUAL_INT(spillover_fx, cfg.spill_fx); + TEST_ASSERT_EQUAL_INT(cmp_par_exp_flags, cfg.cmp_par_exp_flags); + TEST_ASSERT_EQUAL_INT(spillover_exp_flags, cfg.spill_exp_flags); + TEST_ASSERT_EQUAL_INT(cmp_par_efx, cfg.cmp_par_efx); + TEST_ASSERT_EQUAL_INT(spillover_efx, cfg.spill_efx); + + /* invalid spillover_efx parameter */ + spillover_efx = 0; + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_TRUE(error); + + + /* test DATA_TYPE_S_FX_NCOB */ + cfg = cmp_cfg_icu_create(DATA_TYPE_S_FX_NCOB, CMP_MODE_MODEL_ZERO, 0, 1); + cmp_par_exp_flags = MAX_ICU_GOLOMB_PAR; + spillover_exp_flags = cmp_icu_max_spill(cmp_par_exp_flags); + cmp_par_fx = MIN_ICU_GOLOMB_PAR; + spillover_fx = MIN_ICU_SPILL; + cmp_par_ncob = 19; + spillover_ncob = 5; + cmp_par_efx = ~0; /* invalid parameter */ + spillover_efx = ~0; /* invalid parameter */ + cmp_par_ecob = ~0; /* invalid parameter */ + spillover_ecob = ~0; /* invalid parameter */ + cmp_par_fx_cob_variance = ~0; /* invalid parameter */ + spillover_fx_cob_variance = ~0; /* invalid parameter */ + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cmp_par_fx, cfg.cmp_par_fx); + TEST_ASSERT_EQUAL_INT(spillover_fx, cfg.spill_fx); + TEST_ASSERT_EQUAL_INT(cmp_par_exp_flags, cfg.cmp_par_exp_flags); + TEST_ASSERT_EQUAL_INT(spillover_exp_flags, cfg.spill_exp_flags); + TEST_ASSERT_EQUAL_INT(cmp_par_ncob, cfg.cmp_par_ncob); + TEST_ASSERT_EQUAL_INT(spillover_ncob, cfg.spill_ncob); + + /* invalid cmp_par_ncob parameter */ + cmp_par_ncob = 0; + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_TRUE(error); + + + /* test DATA_TYPE_S_FX_DFX_NCOB_ECOB */ + cfg = cmp_cfg_icu_create(DATA_TYPE_S_FX_DFX_NCOB_ECOB, CMP_MODE_DIFF_ZERO, 7, CMP_LOSSLESS); + cmp_par_exp_flags = MAX_ICU_GOLOMB_PAR; + spillover_exp_flags = cmp_icu_max_spill(cmp_par_exp_flags); + cmp_par_fx = MIN_ICU_GOLOMB_PAR; + spillover_fx = MIN_ICU_SPILL; + cmp_par_ncob = 19; + spillover_ncob = 5; + cmp_par_efx = 23; + spillover_efx = 42; + cmp_par_ecob = MAX_ICU_GOLOMB_PAR; + spillover_ecob = MIN_ICU_SPILL; + cmp_par_fx_cob_variance = ~0; /* invalid parameter */ + spillover_fx_cob_variance = ~0; /* invalid parameter */ + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cmp_par_fx, cfg.cmp_par_fx); + TEST_ASSERT_EQUAL_INT(spillover_fx, cfg.spill_fx); + TEST_ASSERT_EQUAL_INT(cmp_par_exp_flags, cfg.cmp_par_exp_flags); + TEST_ASSERT_EQUAL_INT(spillover_exp_flags, cfg.spill_exp_flags); + TEST_ASSERT_EQUAL_INT(cmp_par_ncob, cfg.cmp_par_ncob); + TEST_ASSERT_EQUAL_INT(spillover_ncob, cfg.spill_ncob); + TEST_ASSERT_EQUAL_INT(cmp_par_efx, cfg.cmp_par_efx); + TEST_ASSERT_EQUAL_INT(spillover_efx, cfg.spill_efx); + TEST_ASSERT_EQUAL_INT(cmp_par_ecob, cfg.cmp_par_ecob); + TEST_ASSERT_EQUAL_INT(spillover_ecob, cfg.spill_ecob); + + /* invalid cmp_par_ecob parameter */ + cmp_par_ecob = -1U; + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_TRUE(error); + + + /* DATA_TYPE_L_FX */ + cfg = cmp_cfg_icu_create(DATA_TYPE_L_FX, CMP_MODE_DIFF_ZERO, 7, CMP_LOSSLESS); + cmp_par_exp_flags = MAX_ICU_GOLOMB_PAR; + spillover_exp_flags = cmp_icu_max_spill(cmp_par_exp_flags); + cmp_par_fx = MIN_ICU_GOLOMB_PAR; + spillover_fx = MIN_ICU_SPILL; + cmp_par_ncob = ~0; /* invalid parameter */ + spillover_ncob = ~0; /* invalid parameter */ + cmp_par_efx = ~0; /* invalid parameter */ + spillover_efx = ~0; /* invalid parameter */ + cmp_par_ecob = ~0; /* invalid parameter */ + spillover_ecob = ~0; /* invalid parameter */ + cmp_par_fx_cob_variance = 30; + spillover_fx_cob_variance = 8; + + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cmp_par_fx, cfg.cmp_par_fx); + TEST_ASSERT_EQUAL_INT(spillover_fx, cfg.spill_fx); + TEST_ASSERT_EQUAL_INT(cmp_par_exp_flags, cfg.cmp_par_exp_flags); + TEST_ASSERT_EQUAL_INT(spillover_exp_flags, cfg.spill_exp_flags); + TEST_ASSERT_EQUAL_INT(cmp_par_fx_cob_variance, cfg.cmp_par_fx_cob_variance); + TEST_ASSERT_EQUAL_INT(spillover_fx_cob_variance, cfg.spill_fx_cob_variance); + + /* invalid spillover_fx_cob_variance parameter */ + spillover_fx_cob_variance = 1; + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_TRUE(error); + + + /* DATA_TYPE_L_FX_DFX */ + cfg = cmp_cfg_icu_create(DATA_TYPE_L_FX_DFX, CMP_MODE_DIFF_ZERO, 7, CMP_LOSSLESS); + cmp_par_exp_flags = MAX_ICU_GOLOMB_PAR; + spillover_exp_flags = cmp_icu_max_spill(cmp_par_exp_flags); + cmp_par_fx = MIN_ICU_GOLOMB_PAR; + spillover_fx = MIN_ICU_SPILL; + cmp_par_ncob = ~0; /* invalid parameter */ + spillover_ncob = ~0; /* invalid parameter */ + cmp_par_efx = 23; + spillover_efx = 42; + cmp_par_ecob = ~0; /* invalid parameter */ + spillover_ecob = ~0; /* invalid parameter */ + cmp_par_fx_cob_variance = 30; + spillover_fx_cob_variance = 8; + + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cmp_par_fx, cfg.cmp_par_fx); + TEST_ASSERT_EQUAL_INT(spillover_fx, cfg.spill_fx); + TEST_ASSERT_EQUAL_INT(cmp_par_exp_flags, cfg.cmp_par_exp_flags); + TEST_ASSERT_EQUAL_INT(spillover_exp_flags, cfg.spill_exp_flags); + TEST_ASSERT_EQUAL_INT(cmp_par_efx, cfg.cmp_par_efx); + TEST_ASSERT_EQUAL_INT(spillover_efx, cfg.spill_efx); + TEST_ASSERT_EQUAL_INT(cmp_par_fx_cob_variance, cfg.cmp_par_fx_cob_variance); + TEST_ASSERT_EQUAL_INT(spillover_fx_cob_variance, cfg.spill_fx_cob_variance); + + + /* DATA_TYPE_L_FX_NCOB */ + cfg = cmp_cfg_icu_create(DATA_TYPE_L_FX_NCOB, CMP_MODE_DIFF_ZERO, 7, CMP_LOSSLESS); + cmp_par_exp_flags = MAX_ICU_GOLOMB_PAR; + spillover_exp_flags = cmp_icu_max_spill(cmp_par_exp_flags); + cmp_par_fx = MIN_ICU_GOLOMB_PAR; + spillover_fx = MIN_ICU_SPILL; + cmp_par_ncob = 19; + spillover_ncob = 5; + cmp_par_efx = ~0; /* invalid parameter */ + spillover_efx = ~0; /* invalid parameter */ + cmp_par_ecob = ~0; /* invalid parameter */ + spillover_ecob = ~0; /* invalid parameter */ + cmp_par_fx_cob_variance = 30; + spillover_fx_cob_variance = 8; + + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cmp_par_fx, cfg.cmp_par_fx); + TEST_ASSERT_EQUAL_INT(spillover_fx, cfg.spill_fx); + TEST_ASSERT_EQUAL_INT(cmp_par_exp_flags, cfg.cmp_par_exp_flags); + TEST_ASSERT_EQUAL_INT(spillover_exp_flags, cfg.spill_exp_flags); + TEST_ASSERT_EQUAL_INT(cmp_par_ncob, cfg.cmp_par_ncob); + TEST_ASSERT_EQUAL_INT(spillover_ncob, cfg.spill_ncob); + TEST_ASSERT_EQUAL_INT(cmp_par_fx_cob_variance, cfg.cmp_par_fx_cob_variance); + TEST_ASSERT_EQUAL_INT(spillover_fx_cob_variance, cfg.spill_fx_cob_variance); + + + /* DATA_TYPE_L_FX_DFX_NCOB_ECOB */ + cfg = cmp_cfg_icu_create(DATA_TYPE_L_FX_DFX_NCOB_ECOB, CMP_MODE_DIFF_ZERO, 7, CMP_LOSSLESS); + cmp_par_exp_flags = MAX_ICU_GOLOMB_PAR; + spillover_exp_flags = cmp_icu_max_spill(cmp_par_exp_flags); + cmp_par_fx = MIN_ICU_GOLOMB_PAR; + spillover_fx = MIN_ICU_SPILL; + cmp_par_ncob = 19; + spillover_ncob = 5; + cmp_par_efx = 23; + spillover_efx = 42; + cmp_par_ecob = MAX_ICU_GOLOMB_PAR; + spillover_ecob = MIN_ICU_SPILL; + cmp_par_fx_cob_variance = 30; + spillover_fx_cob_variance = 8; + + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cmp_par_fx, cfg.cmp_par_fx); + TEST_ASSERT_EQUAL_INT(spillover_fx, cfg.spill_fx); + TEST_ASSERT_EQUAL_INT(cmp_par_exp_flags, cfg.cmp_par_exp_flags); + TEST_ASSERT_EQUAL_INT(spillover_exp_flags, cfg.spill_exp_flags); + TEST_ASSERT_EQUAL_INT(cmp_par_efx, cfg.cmp_par_efx); + TEST_ASSERT_EQUAL_INT(spillover_efx, cfg.spill_efx); + TEST_ASSERT_EQUAL_INT(cmp_par_ncob, cfg.cmp_par_ncob); + TEST_ASSERT_EQUAL_INT(spillover_ncob, cfg.spill_ncob); + TEST_ASSERT_EQUAL_INT(cmp_par_ecob, cfg.cmp_par_ecob); + TEST_ASSERT_EQUAL_INT(spillover_ecob, cfg.spill_ecob); + TEST_ASSERT_EQUAL_INT(cmp_par_fx_cob_variance, cfg.cmp_par_fx_cob_variance); + TEST_ASSERT_EQUAL_INT(spillover_fx_cob_variance, cfg.spill_fx_cob_variance); + + + /* DATA_TYPE_F_FX */ + cfg = cmp_cfg_icu_create(DATA_TYPE_F_FX, CMP_MODE_DIFF_ZERO, 7, CMP_LOSSLESS); + cmp_par_exp_flags = ~0; /* invalid parameter */ + spillover_exp_flags = ~0; /* invalid parameter */ + cmp_par_fx = MIN_ICU_GOLOMB_PAR; + spillover_fx = MIN_ICU_SPILL; + cmp_par_ncob = ~0; /* invalid parameter */ + spillover_ncob = ~0; /* invalid parameter */ + cmp_par_efx = ~0; /* invalid parameter */ + spillover_efx = ~0; /* invalid parameter */ + cmp_par_ecob = ~0; /* invalid parameter */ + spillover_ecob = ~0; /* invalid parameter */ + cmp_par_fx_cob_variance = ~0; /* invalid parameter */ + spillover_fx_cob_variance = ~0; /* invalid parameter */ + + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cmp_par_fx, cfg.cmp_par_fx); + TEST_ASSERT_EQUAL_INT(spillover_fx, cfg.spill_fx); + + + /* DATA_TYPE_F_FX_DFX */ + cfg = cmp_cfg_icu_create(DATA_TYPE_F_FX_DFX, CMP_MODE_DIFF_ZERO, 7, CMP_LOSSLESS); + cmp_par_exp_flags = ~0; /* invalid parameter */ + spillover_exp_flags = ~0; /* invalid parameter */ + cmp_par_fx = MIN_ICU_GOLOMB_PAR; + spillover_fx = MIN_ICU_SPILL; + cmp_par_ncob = ~0; /* invalid parameter */ + spillover_ncob = ~0; /* invalid parameter */ + cmp_par_efx = 23; + spillover_efx = 42; + cmp_par_ecob = ~0; /* invalid parameter */ + spillover_ecob = ~0; /* invalid parameter */ + cmp_par_fx_cob_variance = ~0; /* invalid parameter */ + spillover_fx_cob_variance = ~0; /* invalid parameter */ + + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cmp_par_fx, cfg.cmp_par_fx); + TEST_ASSERT_EQUAL_INT(spillover_fx, cfg.spill_fx); + TEST_ASSERT_EQUAL_INT(cmp_par_efx, cfg.cmp_par_efx); + TEST_ASSERT_EQUAL_INT(spillover_efx, cfg.spill_efx); + + + /* DATA_TYPE_F_FX_NCOB */ + cfg = cmp_cfg_icu_create(DATA_TYPE_F_FX_NCOB, CMP_MODE_DIFF_ZERO, 7, CMP_LOSSLESS); + cmp_par_exp_flags = ~0; /* invalid parameter */ + spillover_exp_flags = ~0; /* invalid parameter */ + cmp_par_fx = MIN_ICU_GOLOMB_PAR; + spillover_fx = MIN_ICU_SPILL; + cmp_par_ncob = MIN_ICU_GOLOMB_PAR; + spillover_ncob = cmp_icu_max_spill(cmp_par_ncob); + cmp_par_efx = ~0; /* invalid parameter */ + spillover_efx = ~0; /* invalid parameter */ + cmp_par_ecob = ~0; /* invalid parameter */ + spillover_ecob = ~0; /* invalid parameter */ + cmp_par_fx_cob_variance = ~0; /* invalid parameter */ + spillover_fx_cob_variance = ~0; /* invalid parameter */ + + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cmp_par_fx, cfg.cmp_par_fx); + TEST_ASSERT_EQUAL_INT(spillover_fx, cfg.spill_fx); + TEST_ASSERT_EQUAL_INT(cmp_par_ncob, cfg.cmp_par_ncob); + TEST_ASSERT_EQUAL_INT(spillover_ncob, cfg.spill_ncob); + + + /* DATA_TYPE_F_FX_DFX_NCOB_ECOB */ + cfg = cmp_cfg_icu_create(DATA_TYPE_F_FX_DFX_NCOB_ECOB, CMP_MODE_DIFF_ZERO, 7, CMP_LOSSLESS); + cmp_par_exp_flags = ~0; /* invalid parameter */ + spillover_exp_flags = ~0; /* invalid parameter */ + cmp_par_fx = MIN_ICU_GOLOMB_PAR; + spillover_fx = MIN_ICU_SPILL; + cmp_par_ncob = MIN_ICU_GOLOMB_PAR; + spillover_ncob = cmp_icu_max_spill(cmp_par_ncob); + cmp_par_efx = 23; + spillover_efx = 42; + cmp_par_ecob = MAX_ICU_GOLOMB_PAR; + spillover_ecob = MIN_ICU_SPILL; + cmp_par_fx_cob_variance = ~0; /* invalid parameter */ + spillover_fx_cob_variance = ~0; /* invalid parameter */ + + error = cmp_cfg_fx_cob(&cfg, cmp_par_exp_flags, spillover_exp_flags, + cmp_par_fx, spillover_fx, cmp_par_ncob, spillover_ncob, + cmp_par_efx, spillover_efx, cmp_par_ecob, spillover_ecob, + cmp_par_fx_cob_variance, spillover_fx_cob_variance); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(cmp_par_fx, cfg.cmp_par_fx); + TEST_ASSERT_EQUAL_INT(spillover_fx, cfg.spill_fx); + TEST_ASSERT_EQUAL_INT(cmp_par_ncob, cfg.cmp_par_ncob); + TEST_ASSERT_EQUAL_INT(spillover_ncob, cfg.spill_ncob); + TEST_ASSERT_EQUAL_INT(cmp_par_efx, cfg.cmp_par_efx); + TEST_ASSERT_EQUAL_INT(spillover_efx, cfg.spill_efx); + TEST_ASSERT_EQUAL_INT(cmp_par_ecob, cfg.cmp_par_ecob); + TEST_ASSERT_EQUAL_INT(spillover_ecob, cfg.spill_ecob); +} + +/** + * @test cmp_cfg_aux + */ + +void test_cmp_cfg_aux(void) +{ struct cmp_cfg cfg; + uint32_t cmp_par_mean = 2; + uint32_t spillover_mean = 2; + uint32_t cmp_par_variance = 2; + uint32_t spillover_variance = 2; + uint32_t cmp_par_pixels_error = 2; + uint32_t spillover_pixels_error = 2; + int error; + enum cmp_data_type data_type; + + /* wrong data type test */ + for (data_type = 0; data_type <= DATA_TYPE_F_CAM_BACKGROUND; data_type++) { + cfg = cmp_cfg_icu_create(data_type, CMP_MODE_MODEL_ZERO, 16, CMP_LOSSLESS); + error = cmp_cfg_aux(&cfg, cmp_par_mean, spillover_mean, + cmp_par_variance, spillover_variance, + cmp_par_pixels_error, spillover_pixels_error); + if (data_type == DATA_TYPE_OFFSET || + data_type == DATA_TYPE_BACKGROUND || + data_type == DATA_TYPE_SMEARING + /* data_type == DATA_TYPE_F_CAM_OFFSET || */ + /* data_type == DATA_TYPE_F_CAM_BACKGROUND */ + ) { + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(data_type, cfg.data_type); + TEST_ASSERT_EQUAL_INT(2, cfg.cmp_par_mean); + TEST_ASSERT_EQUAL_INT(2, cfg.spill_mean); + TEST_ASSERT_EQUAL_INT(2, cfg.cmp_par_variance); + TEST_ASSERT_EQUAL_INT(2, cfg.spill_variance); + TEST_ASSERT_EQUAL_INT(2, cfg.cmp_par_pixels_error); + TEST_ASSERT_EQUAL_INT(2, cfg.spill_pixels_error); + } else { + TEST_ASSERT_TRUE(error); + } + } + + /* cfg == NULL test */ + error = cmp_cfg_aux(NULL, cmp_par_mean, spillover_mean, + cmp_par_variance, spillover_variance, + cmp_par_pixels_error, spillover_pixels_error); + TEST_ASSERT_TRUE(error); + + + /* DATA_TYPE_OFFSET */ + cfg = cmp_cfg_icu_create(DATA_TYPE_OFFSET, CMP_MODE_DIFF_ZERO, 7, CMP_LOSSLESS); + cmp_par_mean = MIN_ICU_GOLOMB_PAR; + spillover_mean = cmp_icu_max_spill(MIN_ICU_GOLOMB_PAR); + cmp_par_variance = MIN_ICU_GOLOMB_PAR; + spillover_variance = MIN_ICU_SPILL; + cmp_par_pixels_error = ~0; + spillover_pixels_error = ~0; + + error = cmp_cfg_aux(&cfg, cmp_par_mean, spillover_mean, + cmp_par_variance, spillover_variance, + cmp_par_pixels_error, spillover_pixels_error); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(MIN_ICU_GOLOMB_PAR, cfg.cmp_par_mean); + TEST_ASSERT_EQUAL_INT(cmp_icu_max_spill(MIN_ICU_GOLOMB_PAR), cfg.spill_mean); + TEST_ASSERT_EQUAL_INT(MIN_ICU_GOLOMB_PAR, cfg.cmp_par_variance); + TEST_ASSERT_EQUAL_INT(2, cfg.spill_variance); + + /* This should fail */ + cmp_par_mean = MIN_ICU_GOLOMB_PAR-1; + error = cmp_cfg_aux(&cfg, cmp_par_mean, spillover_mean, + cmp_par_variance, spillover_variance, + cmp_par_pixels_error, spillover_pixels_error); + TEST_ASSERT_TRUE(error); + + + /* DATA_TYPE_BACKGROUND */ + cfg = cmp_cfg_icu_create(DATA_TYPE_BACKGROUND, CMP_MODE_DIFF_ZERO, 7, CMP_LOSSLESS); + cmp_par_mean = MAX_ICU_GOLOMB_PAR; + spillover_mean = cmp_icu_max_spill(MAX_ICU_GOLOMB_PAR); + cmp_par_variance = MIN_ICU_GOLOMB_PAR; + spillover_variance = MIN_ICU_SPILL; + cmp_par_pixels_error = 42; + spillover_pixels_error = 23; + + error = cmp_cfg_aux(&cfg, cmp_par_mean, spillover_mean, + cmp_par_variance, spillover_variance, + cmp_par_pixels_error, spillover_pixels_error); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(MAX_ICU_GOLOMB_PAR, cfg.cmp_par_mean); + TEST_ASSERT_EQUAL_INT(cmp_icu_max_spill(MAX_ICU_GOLOMB_PAR), cfg.spill_mean); + TEST_ASSERT_EQUAL_INT(MIN_ICU_GOLOMB_PAR, cfg.cmp_par_variance); + TEST_ASSERT_EQUAL_INT(MIN_ICU_SPILL, cfg.spill_variance); + TEST_ASSERT_EQUAL_INT(42, cfg.cmp_par_pixels_error); + TEST_ASSERT_EQUAL_INT(23, cfg.spill_pixels_error); + + /* This should fail */ + cmp_par_variance = MIN_ICU_GOLOMB_PAR-1; + error = cmp_cfg_aux(&cfg, cmp_par_mean, spillover_mean, + cmp_par_variance, spillover_variance, + cmp_par_pixels_error, spillover_pixels_error); + TEST_ASSERT_TRUE(error); + + + /* DATA_TYPE_SMEARING */ + cfg = cmp_cfg_icu_create(DATA_TYPE_SMEARING, CMP_MODE_DIFF_ZERO, 7, CMP_LOSSLESS); + cmp_par_mean = MAX_ICU_GOLOMB_PAR; + spillover_mean = cmp_icu_max_spill(MAX_ICU_GOLOMB_PAR); + cmp_par_variance = MIN_ICU_GOLOMB_PAR; + spillover_variance = MIN_ICU_SPILL; + cmp_par_pixels_error = 42; + spillover_pixels_error = 23; + + error = cmp_cfg_aux(&cfg, cmp_par_mean, spillover_mean, + cmp_par_variance, spillover_variance, + cmp_par_pixels_error, spillover_pixels_error); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_INT(MAX_ICU_GOLOMB_PAR, cfg.cmp_par_mean); + TEST_ASSERT_EQUAL_INT(cmp_icu_max_spill(MAX_ICU_GOLOMB_PAR), cfg.spill_mean); + TEST_ASSERT_EQUAL_INT(MIN_ICU_GOLOMB_PAR, cfg.cmp_par_variance); + TEST_ASSERT_EQUAL_INT(MIN_ICU_SPILL, cfg.spill_variance); + TEST_ASSERT_EQUAL_INT(42, cfg.cmp_par_pixels_error); + TEST_ASSERT_EQUAL_INT(23, cfg.spill_pixels_error); + + /* This should fail */ + spillover_pixels_error = cmp_icu_max_spill(42)+1; + error = cmp_cfg_aux(&cfg, cmp_par_mean, spillover_mean, + cmp_par_variance, spillover_variance, + cmp_par_pixels_error, spillover_pixels_error); + TEST_ASSERT_TRUE(error); + +#if 0 +TODO: implemented F_CAM DATA_TYPE_F_CAM_OFFSET and DATA_TYPE_F_CAM_BACKGROUND + /* DATA_TYPE_F_CAM_OFFSET */ + cfg = cmp_cfg_icu_create(DATA_TYPE_F_CAM_OFFSET, CMP_MODE_DIFF_ZERO, 7, CMP_LOSSLESS); + /* DATA_TYPE_F_CAM_BACKGROUND */ + cfg = cmp_cfg_icu_create(DATA_TYPE_F_CAM_BACKGROUND, CMP_MODE_DIFF_ZERO, 7, CMP_LOSSLESS); +#endif +} /** @@ -518,6 +1658,7 @@ void test_put_n_bits32(void) void test_rice_encoder(void) { uint32_t value, g_par, log2_g_par, cw, cw_len; + const uint32_t MAX_GOLOMB_PAR = 0x80000000; /* test minimum Golomb parameter */ value = 0; log2_g_par = (uint32_t)ilog_2(MIN_ICU_GOLOMB_PAR); g_par = 1U << log2_g_par; cw = ~0U; @@ -557,7 +1698,7 @@ void test_rice_encoder(void) TEST_ASSERT_EQUAL_HEX(0xFFFFFFEF, cw); /* test maximum Golomb parameter for rice_encoder */ - value = 0; log2_g_par = (uint32_t)ilog_2(MAX_ICU_GOLOMB_PAR); g_par = 1U << log2_g_par; cw = ~0U; + value = 0; log2_g_par = (uint32_t)ilog_2(MAX_GOLOMB_PAR); g_par = 1U << log2_g_par; cw = ~0U; cw_len = rice_encoder(value, g_par, log2_g_par, &cw); TEST_ASSERT_EQUAL_INT(32, cw_len); TEST_ASSERT_EQUAL_HEX(0x0, cw); @@ -583,9 +1724,10 @@ void test_rice_encoder(void) * @test golomb_encoder */ -void test_Golomb_encoder(void) +void test_golomb_encoder(void) { uint32_t value, g_par, log2_g_par, cw, cw_len; + const uint32_t MAX_GOLOMB_PAR = 0x80000000; /* test minimum Golomb parameter */ value = 0; g_par = MIN_ICU_GOLOMB_PAR; log2_g_par = (uint32_t)ilog_2(g_par); cw = ~0U; @@ -659,12 +1801,12 @@ void test_Golomb_encoder(void) /* test maximum Golomb parameter for golomb_encoder */ - value = 0; g_par = MAX_ICU_GOLOMB_PAR; log2_g_par = (uint32_t)ilog_2(g_par); cw = ~0U; + value = 0; g_par = MAX_GOLOMB_PAR; log2_g_par = (uint32_t)ilog_2(g_par); cw = ~0U; cw_len = golomb_encoder(value, g_par, log2_g_par, &cw); TEST_ASSERT_EQUAL_INT(32, cw_len); TEST_ASSERT_EQUAL_HEX(0x0, cw); - value = 1; g_par = MAX_ICU_GOLOMB_PAR; log2_g_par = (uint32_t)ilog_2(g_par); cw = ~0U; + value = 1; g_par = MAX_GOLOMB_PAR; log2_g_par = (uint32_t)ilog_2(g_par); cw = ~0U; cw_len = golomb_encoder(value, g_par, log2_g_par, &cw); TEST_ASSERT_EQUAL_INT(32, cw_len); TEST_ASSERT_EQUAL_HEX(0x1, cw); @@ -1010,6 +2152,7 @@ void test_encode_value(void) /** * @test cmp_get_max_used_bits + * TODO: move this test */ void test_cmp_get_max_used_bits(void) @@ -1058,6 +2201,188 @@ void test_cmp_get_max_used_bits(void) } +/** + * @test configure_encoder_setup + */ + +void test_configure_encoder_setup(void) +{ + struct encoder_setupt setup; + uint32_t cmp_par; + uint32_t spillover; + uint32_t lossy_par; + uint32_t max_data_bits; + struct cmp_cfg cfg; + int error; + + /* test Golomb encoder zero escape mechanism */ + cmp_par = 42; + spillover = 23; + lossy_par = 0; + max_data_bits = 15; + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.cmp_mode = CMP_MODE_MODEL_ZERO; + cfg.icu_output_buf = (void *)123; + cfg.buffer_length = 2; + error = configure_encoder_setup(&setup, cmp_par, spillover,lossy_par, + max_data_bits, &cfg); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL(golomb_encoder, setup.generate_cw_f); /* pointer to the code word encoder */ + TEST_ASSERT_EQUAL(encode_value_zero, setup.encode_method_f); /* pointer to the encoding function */ + TEST_ASSERT_EQUAL(123, setup.bitstream_adr); /* start address of the compressed data bitstream */ + TEST_ASSERT_EQUAL_INT(32, setup.max_stream_len); /* maximum length of the bitstream/icu_output_buf in bits */ + TEST_ASSERT_EQUAL_INT(42, setup.encoder_par1); /* encoding parameter 1 */ + TEST_ASSERT_EQUAL_INT(5, setup.encoder_par2); /* encoding parameter 2 */ + TEST_ASSERT_EQUAL_INT(23, setup.spillover_par); /* outlier parameter */ + TEST_ASSERT_EQUAL_INT(0, setup.lossy_par); /* lossy compression parameter */ + TEST_ASSERT_EQUAL_INT(15, setup.max_data_bits); /* how many bits are needed to represent the highest possible value */ + memset(&setup, 0, sizeof(setup)); + + /* test Rice encoder multi escape mechanism */ + cmp_par = 32; + spillover = 23; + lossy_par = 0; + max_data_bits = 32; + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.cmp_mode = CMP_MODE_DIFF_MULTI; + cfg.icu_output_buf = (void *)123; + cfg.buffer_length = 2; + error = configure_encoder_setup(&setup, cmp_par, spillover,lossy_par, + max_data_bits, &cfg); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL(rice_encoder, setup.generate_cw_f); /* pointer to the code word encoder */ + TEST_ASSERT_EQUAL(encode_value_multi, setup.encode_method_f); /* pointer to the encoding function */ + TEST_ASSERT_EQUAL(123, setup.bitstream_adr); /* start address of the compressed data bitstream */ + TEST_ASSERT_EQUAL_INT(32, setup.max_stream_len); /* maximum length of the bitstream/icu_output_buf in bits */ + TEST_ASSERT_EQUAL_INT(32, setup.encoder_par1); /* encoding parameter 1 */ + TEST_ASSERT_EQUAL_INT(5, setup.encoder_par2); /* encoding parameter 2 */ + TEST_ASSERT_EQUAL_INT(23, setup.spillover_par); /* outlier parameter */ + TEST_ASSERT_EQUAL_INT(0, setup.lossy_par); /* lossy compression parameter */ + TEST_ASSERT_EQUAL_INT(32, setup.max_data_bits); /* how many bits are needed to represent the highest possible value */ + memset(&setup, 0, sizeof(setup)); + + /* test CMP_MODE_STUFF */ + cmp_par = 32; + spillover = ~0; + lossy_par = 1; + max_data_bits = 32; + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.cmp_mode = CMP_MODE_STUFF; + cfg.icu_output_buf = (void *)123; + cfg.buffer_length = 2; + error = configure_encoder_setup(&setup, cmp_par, spillover,lossy_par, + max_data_bits, &cfg); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL(NULL, setup.generate_cw_f); /* pointer to the code word encoder */ + TEST_ASSERT_EQUAL(encode_value_none, setup.encode_method_f); /* pointer to the encoding function */ + TEST_ASSERT_EQUAL(123, setup.bitstream_adr); /* start address of the compressed data bitstream */ + TEST_ASSERT_EQUAL_INT(32, setup.max_stream_len); /* maximum length of the bitstream/icu_output_buf in bits */ + TEST_ASSERT_EQUAL_INT(32, setup.encoder_par1); /* encoding parameter 1 */ + TEST_ASSERT_EQUAL_INT(0, setup.encoder_par2); /* encoding parameter 2 */ + TEST_ASSERT_EQUAL_INT(0, setup.spillover_par); /* outlier parameter */ + TEST_ASSERT_EQUAL_INT(1, setup.lossy_par); /* lossy compression parameter */ + TEST_ASSERT_EQUAL_INT(32, setup.max_data_bits); /* how many bits are needed to represent the highest possible value */ + memset(&setup, 0, sizeof(setup)); + + /* test max_used_bits = 33 */ + cmp_par = 32; + spillover = 23; + lossy_par = 0; + max_data_bits = 33; + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.cmp_mode = CMP_MODE_DIFF_MULTI; + cfg.icu_output_buf = (void *)123; + cfg.buffer_length = 2; + error = configure_encoder_setup(&setup, cmp_par, spillover,lossy_par, + max_data_bits, &cfg); + TEST_ASSERT_TRUE(error); + memset(&setup, 0, sizeof(setup)); + + /* cmp_par = 0 test */ + cmp_par = 0; + spillover = 23; + lossy_par = 0; + max_data_bits = 32; + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.cmp_mode = CMP_MODE_DIFF_MULTI; + cfg.icu_output_buf = (void *)123; + cfg.buffer_length = 2; + error = configure_encoder_setup(&setup, cmp_par, spillover,lossy_par, + max_data_bits, &cfg); + TEST_ASSERT_TRUE(error); + memset(&setup, 0, sizeof(setup)); + + /* cmp_par = 0 test STUFF MODE this should work*/ + cmp_par = 0; + spillover = 23; + lossy_par = 0; + max_data_bits = 32; + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.cmp_mode = CMP_MODE_STUFF; + cfg.icu_output_buf = (void *)123; + cfg.buffer_length = 2; + error = configure_encoder_setup(&setup, cmp_par, spillover,lossy_par, + max_data_bits, &cfg); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL(NULL, setup.generate_cw_f); /* pointer to the code word encoder */ + TEST_ASSERT_EQUAL(encode_value_none, setup.encode_method_f); /* pointer to the encoding function */ + TEST_ASSERT_EQUAL(123, setup.bitstream_adr); /* start address of the compressed data bitstream */ + TEST_ASSERT_EQUAL_INT(32, setup.max_stream_len); /* maximum length of the bitstream/icu_output_buf in bits */ + TEST_ASSERT_EQUAL_INT(0, setup.encoder_par1); /* encoding parameter 1 */ + TEST_ASSERT_EQUAL_INT(0, setup.encoder_par2); /* encoding parameter 2 */ + TEST_ASSERT_EQUAL_INT(0, setup.spillover_par); /* outlier parameter */ + TEST_ASSERT_EQUAL_INT(0, setup.lossy_par); /* lossy compression parameter */ + TEST_ASSERT_EQUAL_INT(0, setup.max_data_bits); /* how many bits are needed to represent the highest possible value */ + memset(&setup, 0, sizeof(setup)); + + /* cmp_mode = STUFF_MODE +1 */ + cmp_par = 32; + spillover = 23; + lossy_par = 0; + max_data_bits = 1; + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.cmp_mode = CMP_MODE_STUFF+1; + cfg.icu_output_buf = (void *)123; + cfg.buffer_length = 2; + error = configure_encoder_setup(&setup, cmp_par, spillover,lossy_par, + max_data_bits, &cfg); + TEST_ASSERT_TRUE(error); + memset(&setup, 0, sizeof(setup)); + + /* setup = NULL test */ + cmp_par = 42; + spillover = 23; + lossy_par = 0; + max_data_bits = 15; + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.cmp_mode = CMP_MODE_MODEL_ZERO; + cfg.icu_output_buf = (void *)123; + cfg.buffer_length = 2; + error = configure_encoder_setup(NULL, cmp_par, spillover,lossy_par, + max_data_bits, &cfg); + TEST_ASSERT_TRUE(error); + memset(&setup, 0, sizeof(setup)); + + /* cfg = NULL test */ + cmp_par = 42; + spillover = 23; + lossy_par = 0; + max_data_bits = 15; + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.cmp_mode = CMP_MODE_MODEL_ZERO; + cfg.icu_output_buf = (void *)123; + cfg.buffer_length = 2; + error = configure_encoder_setup(&setup, cmp_par, spillover,lossy_par, + max_data_bits, NULL); + TEST_ASSERT_TRUE(error); + memset(&setup, 0, sizeof(setup)); +} + + +/** + * @test compress_imagette + */ + void test_compress_imagette_diff(void) { uint16_t data[] = {0xFFFF, 1, 0, 42, 0x8000, 0x7FFF, 0xFFFF}; @@ -1081,6 +2406,11 @@ void test_compress_imagette_diff(void) TEST_ASSERT_EQUAL_HEX(0x00000000, be32_to_cpu(output_buf[2])); } + +/** + * @test compress_imagette + */ + void test_compress_imagette_model(void) { uint16_t data[] = {0x0000, 0x0001, 0x0042, 0x8000, 0x7FFF, 0xFFFF, 0xFFFF}; @@ -1116,9 +2446,19 @@ void test_compress_imagette_model(void) TEST_ASSERT_EQUAL_HEX(0x3FFF, model_up[4]); TEST_ASSERT_EQUAL_HEX(0xFFFF, model_up[5]); TEST_ASSERT_EQUAL_HEX(0x7FFF, model_up[6]); + + + /* error case: model mode without model data */ + cfg.model_buf = NULL; /* this is the error */ + cmp_size = icu_compress_data(&cfg); + TEST_ASSERT_EQUAL(-1, cmp_size); } +/** + * @test compress_imagette + */ + void test_compress_imagette_stuff(void) { uint16_t data[] = {0x0, 0x1, 0x23, 0x42, 0x8000, 0x7FFF, 0xFFFF}; @@ -1151,12 +2491,15 @@ void test_compress_imagette_stuff(void) } +/** + * @test compress_imagette + */ + void test_compress_imagette_raw(void) { uint16_t data[] = {0x0, 0x1, 0x23, 0x42, INT16_MIN, INT16_MAX, UINT16_MAX}; - uint16_t output_buf[7] = {0}; + uint16_t output_buf[7] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; struct cmp_cfg cfg = {0}; - int cmp_size; cfg.data_type = DATA_TYPE_IMAGETTE; @@ -1166,9 +2509,7 @@ void test_compress_imagette_raw(void) cfg.icu_output_buf = (uint32_t *)output_buf; cfg.buffer_length = 7; - cmp_size = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(7*16, cmp_size); TEST_ASSERT_EQUAL_HEX16(0x0, be16_to_cpu(output_buf[0])); TEST_ASSERT_EQUAL_HEX16(0x1, be16_to_cpu(output_buf[1])); @@ -1177,6 +2518,181 @@ void test_compress_imagette_raw(void) TEST_ASSERT_EQUAL_HEX16(INT16_MIN, be16_to_cpu(output_buf[4])); TEST_ASSERT_EQUAL_HEX16(INT16_MAX, be16_to_cpu(output_buf[5])); TEST_ASSERT_EQUAL_HEX16(UINT16_MAX, be16_to_cpu(output_buf[6])); + + + /* compressed data buf = NULL test */ + memset(&cfg, 0, sizeof(struct cmp_cfg)); + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.input_buf = data; + cfg.samples = 7; + cfg.icu_output_buf = NULL; + cfg.buffer_length = 7; + + cmp_size = icu_compress_data(&cfg); + TEST_ASSERT_EQUAL_INT(7*16, cmp_size); + + + /* error case: input_buf = NULL */ + memset(&cfg, 0, sizeof(struct cmp_cfg)); + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.input_buf = NULL; /* no data to compress */ + cfg.samples = 7; + cfg.icu_output_buf = (uint32_t *)output_buf; + cfg.buffer_length = 7; + + cmp_size = icu_compress_data(&cfg); + TEST_ASSERT_EQUAL_INT(-1, cmp_size); + + + /* error case: compressed data buffer to small */ + memset(&cfg, 0, sizeof(struct cmp_cfg)); + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.input_buf = data; + cfg.samples = 7; + cfg.icu_output_buf = (uint32_t *)output_buf; + cfg.buffer_length = 6; /* the buffer is to small */ + + cmp_size = icu_compress_data(&cfg); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SAMLL_BUF, cmp_size); +} + + +/** + * @test compress_imagette + */ + +void test_compress_imagette_error_cases(void) +{ + uint16_t data[] = {0xFFFF, 1, 0, 42, 0x8000, 0x7FFF, 0xFFFF}; + uint32_t output_buf[2] = {0xFFFF, 0xFFFF}; + struct cmp_cfg cfg = {0}; + int cmp_size; + + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.cmp_mode = CMP_MODE_DIFF_ZERO; + cfg.input_buf = NULL; + cfg.samples = 0; /* nothing to compress */ + cfg.golomb_par = 1; + cfg.spill = 8; + cfg.icu_output_buf = NULL; + cfg.buffer_length = 0; + + cmp_size = icu_compress_data(&cfg); + TEST_ASSERT_EQUAL_INT(0, cmp_size); + + + /* compressed data buffer to small test */ + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.cmp_mode = CMP_MODE_DIFF_ZERO; + cfg.input_buf = data; + cfg.samples = 7; + cfg.golomb_par = 1; + cfg.spill = 8; + cfg.icu_output_buf = (uint32_t *)output_buf; + cfg.buffer_length = 4; + + cmp_size = icu_compress_data(&cfg); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SAMLL_BUF, cmp_size); + + + /* error in setup */ + struct cmp_max_used_bits max_used_bits = cmp_get_max_used_bits(); + max_used_bits.nc_imagette = 33; + cmp_set_max_used_bits(&max_used_bits); + cfg.data_type = DATA_TYPE_IMAGETTE; + cfg.cmp_mode = CMP_MODE_DIFF_ZERO; + cfg.input_buf = data; + cfg.samples = 2; + cfg.golomb_par = 1; + cfg.spill = 8; + cfg.icu_output_buf = (uint32_t *)output_buf; + cfg.buffer_length = 4; + + cmp_size = icu_compress_data(&cfg); + TEST_ASSERT_EQUAL_INT(-1, cmp_size); +} + + +/** + * @test compress_multi_entry_hdr + */ + +void test_compress_multi_entry_hdr(void) +{ + int stream_len; + uint8_t data[MULTI_ENTRY_HDR_SIZE]; + uint8_t model[MULTI_ENTRY_HDR_SIZE]; + uint8_t up_model[MULTI_ENTRY_HDR_SIZE]; + uint8_t cmp_data[MULTI_ENTRY_HDR_SIZE]; + uint8_t *data_p = NULL; + uint8_t *model_p = NULL; + uint8_t *up_model_p = NULL; + + memset(data, 0x42, sizeof(data)); + + /* no data; no cmp_data no model test */ + /* no data; no model; no up_model; no cmp_data */ + stream_len = compress_multi_entry_hdr((void **)&data_p, (void **)&model_p, + (void **)&up_model_p, NULL); + TEST_ASSERT_EQUAL_INT(96, stream_len); + + /* no model; no up_model */ + data_p = data; + stream_len = compress_multi_entry_hdr((void **)&data_p, (void **)&model_p, + (void **)&up_model_p, cmp_data); + TEST_ASSERT_EQUAL_INT(96, stream_len); + TEST_ASSERT_FALSE(memcmp(cmp_data, data, MULTI_ENTRY_HDR_SIZE)); + TEST_ASSERT_EQUAL(data_p-data, MULTI_ENTRY_HDR_SIZE); + + /* no up_model */ + memset(cmp_data, 0, sizeof(cmp_data)); + data_p = data; + model_p = model; + up_model_p = NULL; + stream_len = compress_multi_entry_hdr((void **)&data_p, (void **)&model_p, + (void **)&up_model_p, cmp_data); + TEST_ASSERT_EQUAL_INT(96, stream_len); + TEST_ASSERT_FALSE(memcmp(cmp_data, data, MULTI_ENTRY_HDR_SIZE)); + TEST_ASSERT_EQUAL(data_p-data, MULTI_ENTRY_HDR_SIZE); + TEST_ASSERT_EQUAL(model_p-model, MULTI_ENTRY_HDR_SIZE); + + /* all buffer test */ + memset(cmp_data, 0, sizeof(cmp_data)); + data_p = data; + model_p = model; + up_model_p = up_model; + stream_len = compress_multi_entry_hdr((void **)&data_p, (void **)&model_p, + (void **)&up_model_p, cmp_data); + TEST_ASSERT_EQUAL_INT(96, stream_len); + TEST_ASSERT_FALSE(memcmp(cmp_data, data, MULTI_ENTRY_HDR_SIZE)); + TEST_ASSERT_FALSE(memcmp(up_model, data, MULTI_ENTRY_HDR_SIZE)); + TEST_ASSERT_EQUAL(data_p-data, MULTI_ENTRY_HDR_SIZE); + TEST_ASSERT_EQUAL(model_p-model, MULTI_ENTRY_HDR_SIZE); + TEST_ASSERT_EQUAL(up_model_p-up_model, MULTI_ENTRY_HDR_SIZE); + + /* all buffer test; no cmp_data */ + memset(cmp_data, 0, sizeof(cmp_data)); + data_p = data; + model_p = model; + up_model_p = up_model; + stream_len = compress_multi_entry_hdr((void **)&data_p, (void **)&model_p, + (void **)&up_model_p, NULL); + TEST_ASSERT_EQUAL_INT(96, stream_len); + TEST_ASSERT_FALSE(memcmp(up_model, data, MULTI_ENTRY_HDR_SIZE)); + TEST_ASSERT_EQUAL(data_p-data, MULTI_ENTRY_HDR_SIZE); + TEST_ASSERT_EQUAL(model_p-model, MULTI_ENTRY_HDR_SIZE); + TEST_ASSERT_EQUAL(up_model_p-up_model, MULTI_ENTRY_HDR_SIZE); + + /* no data, use up_model test */ + memset(cmp_data, 0, sizeof(cmp_data)); + data_p = NULL; + model_p = model; + up_model_p = up_model; + stream_len = compress_multi_entry_hdr((void **)&data_p, (void **)&model_p, + (void **)&up_model_p, NULL); + TEST_ASSERT_EQUAL_INT(96, stream_len); + TEST_ASSERT_EQUAL(model_p-model, MULTI_ENTRY_HDR_SIZE); + TEST_ASSERT_EQUAL(up_model_p-up_model, MULTI_ENTRY_HDR_SIZE); } @@ -1363,9 +2879,9 @@ void test_compress_s_fx_model_multi(void) TEST_ASSERT_EQUAL_HEX(0xAFFF4DE5, be32_to_cpu(cmp_data[1])); TEST_ASSERT_EQUAL_HEX(0xCC000000, be32_to_cpu(cmp_data[2])); - TEST_ASSERT_FALSE(memcmp(cfg.input_buf, cfg.icu_output_buf, MULTI_ENTRY_HDR_SIZE)); hdr = cfg.icu_new_model_buf; up_model_buf = (struct s_fx *)hdr->entry; + TEST_ASSERT_FALSE(memcmp(hdr, cfg.icu_output_buf, MULTI_ENTRY_HDR_SIZE)); TEST_ASSERT_EQUAL_HEX(0x0, up_model_buf[0].exp_flags); TEST_ASSERT_EQUAL_HEX(0x0, up_model_buf[0].fx); TEST_ASSERT_EQUAL_HEX(0x2, up_model_buf[1].exp_flags); @@ -1386,3 +2902,139 @@ void test_compress_s_fx_model_multi(void) } +void test_compress_s_fx_efx_model_multi(void) +{ + uint32_t i; + struct s_fx_efx data[6], model[6]; + struct s_fx_efx *up_model_buf; + struct cmp_cfg cfg = {0}; + int cmp_size; + struct multi_entry_hdr *hdr; + uint32_t *cmp_data; + struct cmp_max_used_bits max_used_bits = cmp_get_max_used_bits(); + + /* define max_used_bits */ + max_used_bits.s_exp_flags = 2; + max_used_bits.s_fx = 21; + max_used_bits.s_efx = 21; + cmp_set_max_used_bits(&max_used_bits); + + /* setup configuration */ + cfg.data_type = DATA_TYPE_S_FX_DFX; + cfg.cmp_mode = CMP_MODE_MODEL_MULTI; + cfg.model_value = 16; + cfg.samples = 6; + cfg.input_buf = malloc(cmp_cal_size_of_data(cfg.samples, cfg.data_type)); + TEST_ASSERT_NOT_NULL(cfg.input_buf); + cfg.model_buf = malloc(cmp_cal_size_of_data(cfg.samples, cfg.data_type)); + TEST_ASSERT_NOT_NULL(cfg.model_buf); + cfg.icu_new_model_buf = malloc(cmp_cal_size_of_data(cfg.samples, cfg.data_type)); + TEST_ASSERT_NOT_NULL(cfg.icu_new_model_buf); + cfg.buffer_length = 6; + cfg.icu_output_buf = malloc(cmp_cal_size_of_data(cfg.buffer_length, cfg.data_type)); + TEST_ASSERT_NOT_NULL(cfg.icu_output_buf); + cfg.cmp_par_exp_flags = 1; + cfg.spill_exp_flags = 8; + cfg.cmp_par_fx = 3; + cfg.spill_fx = 35; + cfg.cmp_par_efx = 4; + cfg.spill_efx = 35; + + + /* generate input data */ + hdr = cfg.input_buf; + /* use dummy data for the header */ + memset(hdr, 0x42, sizeof(struct multi_entry_hdr)); + data[0].exp_flags = 0x0; + data[0].fx = 0x0; + data[0].efx = 0x0; + data[1].exp_flags = 0x1; + data[1].fx = 0x1; + data[1].efx = 0; + data[2].exp_flags = 0x2; + data[2].fx = 0x23; + data[2].efx = 0; + data[3].exp_flags = 0x3; + data[3].fx = 0x42; + data[3].efx = 0; + data[4].exp_flags = 0x0; + data[4].fx = 0x001FFFFF; + data[4].efx = 0; + data[5].exp_flags = 0x0; + data[5].fx = 0x0; + data[5].efx = 0; + memcpy(hdr->entry, data, sizeof(data)); + + /* generate model data */ + hdr = cfg.model_buf; + /* use dummy data for the header */ + memset(hdr, 0x41, sizeof(struct multi_entry_hdr)); + model[0].exp_flags = 0x0; + model[0].fx = 0x0; + model[0].efx = 0x1FFFFF; + model[1].exp_flags = 0x3; + model[1].fx = 0x1; + model[1].efx = 0x1FFFFF; + model[2].exp_flags = 0x0; + model[2].fx = 0x42; + model[2].efx = 0x1FFFFF; + model[3].exp_flags = 0x0; + model[3].fx = 0x23; + model[3].efx = 0x1FFFFF; + model[4].exp_flags = 0x3; + model[4].fx = 0x0; + model[4].efx = 0x1FFFFF; + model[5].exp_flags = 0x2; + model[5].fx = 0x001FFFFF; + model[5].efx = 0x1FFFFF; + memcpy(hdr->entry, model, sizeof(model)); + + cmp_size = icu_compress_data(&cfg); +#if 0 + TEST_ASSERT_EQUAL_INT(166, cmp_size); + TEST_ASSERT_FALSE(memcmp(cfg.input_buf, cfg.icu_output_buf, MULTI_ENTRY_HDR_SIZE)); + cmp_data = &cfg.icu_output_buf[MULTI_ENTRY_HDR_SIZE/sizeof(uint32_t)]; + TEST_ASSERT_EQUAL_HEX(0x1C77FFA6, be32_to_cpu(cmp_data[0])); + TEST_ASSERT_EQUAL_HEX(0xAFFF4DE5, be32_to_cpu(cmp_data[1])); + TEST_ASSERT_EQUAL_HEX(0xCC000000, be32_to_cpu(cmp_data[2])); + +#endif + hdr = cfg.icu_new_model_buf; + up_model_buf = (struct s_fx *)hdr->entry; + TEST_ASSERT_FALSE(memcmp(hdr, cfg.icu_output_buf, MULTI_ENTRY_HDR_SIZE)); + for (i = 0; i < cfg.samples; i++) { + TEST_ASSERT_EQUAL(model[i].exp_flags, up_model_buf[i].exp_flags); + TEST_ASSERT_EQUAL(model[i].fx, up_model_buf[i].fx); + TEST_ASSERT_EQUAL(model[i].efx, up_model_buf[i].efx); + } + + + free(cfg.input_buf); + free(cfg.model_buf); + free(cfg.icu_new_model_buf); + free(cfg.icu_output_buf); +} + + +/** + * @test icu_compress_data + */ + +void test_icu_compress_data_error_cases(void) +{ + int cmp_size; + struct cmp_cfg cfg = {0}; + uint16_t data[4] = {0, 0xFFFF, 23, 42}; + uint32_t cmp_data_buf[4] = {0}; + + /* cfg = NULL test */ + cmp_size = icu_compress_data(NULL); + TEST_ASSERT_EQUAL(-1, cmp_size); + + /* samples = 0 test */ + cfg.samples = 0; + cmp_size = icu_compress_data(&cfg); + TEST_ASSERT_EQUAL(0, cmp_size); + +} + -- GitLab