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