From d6e7fa9d97edbf8e3e11c1e47f7277794cc99f35 Mon Sep 17 00:00:00 2001
From: Dominik Loidolt <dominik.loidolt@univie.ac.at>
Date: Tue, 12 Mar 2024 14:40:11 +0100
Subject: [PATCH] Refactor compression decompression round trip test suite

---
 test/cmp_decmp/test_cmp_decmp.c | 915 ++++++++++++++++++--------------
 1 file changed, 531 insertions(+), 384 deletions(-)

diff --git a/test/cmp_decmp/test_cmp_decmp.c b/test/cmp_decmp/test_cmp_decmp.c
index 1331f3d..cddcf6f 100644
--- a/test/cmp_decmp/test_cmp_decmp.c
+++ b/test/cmp_decmp/test_cmp_decmp.c
@@ -15,9 +15,8 @@
  *
  * @brief random compression decompression tests
  * @details We generate random data and compress them with random parameters.
- *	After that we put the data in a compression entity. We decompress the
- *	compression entity and compare the decompressed data with the original
- *	data.
+ *	After that we  decompress the compression entity and compare the
+ *	decompressed data with the original data.
  */
 
 
@@ -32,6 +31,7 @@
 #include <decmp.h>
 #include <cmp_data_types.h>
 #include <leon_inttypes.h>
+#include <byteorder.h>
 
 #if defined __has_include
 #  if __has_include(<time.h>)
@@ -41,13 +41,11 @@
 #  endif
 #endif
 
-#define IMAX_BITS(m) ((m)/((m)%255+1) / 255%255*8 + 7-86/((m)%255+12))
-#define RAND_MAX_WIDTH IMAX_BITS(RAND_MAX)
-
 #define ROUND_UP_TO_MULTIPLE_OF_4(x) (((x) + 3) & ~3)
 
+
 /**
- * @brief  Seeds the pseudo-random number generator used by rand()
+ * @brief  Seeds the pseudo-random number generator
  */
 
 void setUp(void)
@@ -69,14 +67,33 @@ void setUp(void)
 }
 
 
-static size_t gen_ima_data(uint16_t *data, uint32_t samples,
-			   const struct cmp_max_used_bits *max_used_bits)
+static size_t gen_ima_data(uint16_t *data, enum cmp_data_type data_type,
+			   uint32_t samples, const struct cmp_max_used_bits *max_used_bits)
 {
 	uint32_t i;
 
-	if (data)
+	if (data) {
+		uint32_t max_data_bits;
+
+		switch (data_type) {
+		case DATA_TYPE_IMAGETTE:
+		case DATA_TYPE_IMAGETTE_ADAPTIVE:
+			max_data_bits = max_used_bits->nc_imagette;
+			break;
+		case DATA_TYPE_SAT_IMAGETTE:
+		case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE:
+			max_data_bits = max_used_bits->saturated_imagette;
+			break;
+		case DATA_TYPE_F_CAM_IMAGETTE:
+		case DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE:
+			max_data_bits = max_used_bits->fc_imagette;
+			break;
+		default:
+			TEST_FAIL();
+		}
 		for (i = 0; i < samples; i++)
-			data[i] = (uint16_t)cmp_rand_nbits(max_used_bits->nc_imagette);
+			data[i] = (uint16_t)cmp_rand_nbits(max_data_bits);
+	}
 	return sizeof(*data) * samples;
 }
 
@@ -365,86 +382,8 @@ static size_t gen_l_fx_efx_ncob_ecob_data(struct l_fx_efx_ncob_ecob *data, uint3
 }
 
 
-static uint8_t get_sst(enum cmp_data_type data_type)
-{
-	uint8_t sst = 0;
-
-	switch (data_type) {
-	case DATA_TYPE_IMAGETTE:
-	case DATA_TYPE_IMAGETTE_ADAPTIVE:
-		sst = SST_NCxx_S_SCIENCE_IMAGETTE;
-		break;
-	case DATA_TYPE_SAT_IMAGETTE:
-	case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE:
-		sst = SST_NCxx_S_SCIENCE_SAT_IMAGETTE;
-		break;
-	case DATA_TYPE_OFFSET:
-		sst = SST_NCxx_S_SCIENCE_OFFSET;
-		break;
-	case DATA_TYPE_BACKGROUND:
-		sst = SST_NCxx_S_SCIENCE_BACKGROUND;
-		break;
-	case DATA_TYPE_SMEARING:
-		sst = SST_NCxx_S_SCIENCE_SMEARING;
-		break;
-	case DATA_TYPE_S_FX:
-		sst = SST_NCxx_S_SCIENCE_S_FX;
-		break;
-	case DATA_TYPE_S_FX_EFX:
-		sst = SST_NCxx_S_SCIENCE_S_FX_EFX;
-		break;
-	case DATA_TYPE_S_FX_NCOB:
-		sst = SST_NCxx_S_SCIENCE_S_FX_NCOB;
-		break;
-	case DATA_TYPE_S_FX_EFX_NCOB_ECOB:
-		sst = SST_NCxx_S_SCIENCE_S_FX_EFX_NCOB_ECOB;
-		break;
-	case DATA_TYPE_L_FX:
-		sst = SST_NCxx_S_SCIENCE_L_FX;
-		break;
-	case DATA_TYPE_L_FX_EFX:
-		sst = SST_NCxx_S_SCIENCE_L_FX_EFX;
-		break;
-	case DATA_TYPE_L_FX_NCOB:
-		sst = SST_NCxx_S_SCIENCE_L_FX_NCOB;
-		break;
-	case DATA_TYPE_L_FX_EFX_NCOB_ECOB:
-		sst = SST_NCxx_S_SCIENCE_L_FX_EFX_NCOB_ECOB;
-		break;
-	case DATA_TYPE_F_FX:
-		sst = SST_NCxx_S_SCIENCE_F_FX;
-		break;
-	case DATA_TYPE_F_FX_EFX:
-		sst = SST_NCxx_S_SCIENCE_F_FX_EFX;
-		break;
-	case DATA_TYPE_F_FX_NCOB:
-		sst = SST_NCxx_S_SCIENCE_F_FX_NCOB;
-		break;
-	case DATA_TYPE_F_FX_EFX_NCOB_ECOB:
-		sst = SST_NCxx_S_SCIENCE_F_FX_EFX_NCOB_ECOB;
-		break;
-	case DATA_TYPE_F_CAM_IMAGETTE:
-	case DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE:
-		sst = SST_FCx_S_SCIENCE_IMAGETTE;
-		break;
-	case DATA_TYPE_F_CAM_OFFSET:
-		sst = SST_FCx_S_SCIENCE_OFFSET_VALUES;
-		break;
-	case DATA_TYPE_F_CAM_BACKGROUND:
-		sst = SST_FCx_S_BACKGROUND_VALUES;
-		break;
-	default:
-	case DATA_TYPE_UNKNOWN:
-		TEST_FAIL();
-		/* debug_print("Error: Unknown compression data type!\n"); */
-	};
-
-	return sst;
-}
-
-
-size_t generate_random_collection_hdr(struct collection_hdr *col, enum cmp_data_type data_type,
-				      uint32_t samples)
+uint32_t generate_random_collection_hdr(struct collection_hdr *col, enum cmp_data_type data_type,
+					uint32_t samples)
 {
 	static uint8_t sequence_num;
 	size_t data_size = size_of_a_sample(data_type)*samples;
@@ -452,11 +391,15 @@ size_t generate_random_collection_hdr(struct collection_hdr *col, enum cmp_data_
 	TEST_ASSERT(data_size <= UINT16_MAX);
 
 	if (col) {
+#ifdef HAS_TIME_H
 		TEST_ASSERT_FALSE(cmp_col_set_timestamp(col, cmp_ent_create_timestamp(NULL)));
+#else
+		TEST_ASSERT_FALSE(cmp_col_set_timestamp(col, 0x150D15AB1ED));
+#endif
 		TEST_ASSERT_FALSE(cmp_col_set_configuration_id(col, (uint16_t)cmp_rand32()));
 
 		TEST_ASSERT_FALSE(cmp_col_set_pkt_type(col, COL_SCI_PKTS_TYPE));
-		TEST_ASSERT_FALSE(cmp_col_set_subservice(col, get_sst(data_type)));
+		TEST_ASSERT_FALSE(cmp_col_set_subservice(col, convert_cmp_data_type_to_subservice(data_type)));
 		TEST_ASSERT_FALSE(cmp_col_set_ccd_id(col, (uint8_t)cmp_rand_between(0, 3)));
 		TEST_ASSERT_FALSE(cmp_col_set_sequence_num(col, sequence_num++));
 
@@ -467,13 +410,17 @@ size_t generate_random_collection_hdr(struct collection_hdr *col, enum cmp_data_
 
 
 /**
- * @brief generate random test data
+ * @brief generates a random collection (with header)
  *
- * @param samples	number of random test samples
- * @param data_type	compression data type of the test data
- * @param max_used_bits	pointer to a max_used_bits structure
+ * @param col		pointer to where the random collection will be stored;
+ *			if NULL, the function will only return the size of the
+ *			random collection
+ * @param data_type	specifies the compression data type of the test data
+ * @param samples	the number of random test data samples to generate
+ * @param max_used_bits	pointer to a structure that tracks the maximum number of
+ *			bits used
  *
- * @returns a pointer to the generated random test data
+ * @return the size of the generated random collection in bytes
  */
 
 size_t generate_random_collection(struct collection_hdr *col, enum cmp_data_type data_type,
@@ -485,22 +432,17 @@ size_t generate_random_collection(struct collection_hdr *col, enum cmp_data_type
 	if (col)
 		science_data = col->entry;
 
-	if (rdcu_supported_data_type_is_used(data_type)) {
-		/* for the rdcu the header counts as data */
-		size_t hdr_in_samples = COLLECTION_HDR_SIZE/size_of_a_sample(data_type);
-		TEST_ASSERT(samples >= hdr_in_samples);
-		samples -= hdr_in_samples;
-	}
-
 	size = generate_random_collection_hdr(col, data_type, samples);
-	/* TDOO remove me */
-	int i;
-	for (i = 0; i < size_of_a_sample(data_type)*samples; ++i) {
-		if (col){
-			col->entry[i] = i;
+#if 0
+	{	int i;
+
+		for (i = 0; i < size_of_a_sample(data_type)*samples; i++) {
+			if (col)
+				col->entry[i] = i;
 		}
+		return size+i;
 	}
-	return size+i;
+#endif
 
 	switch (data_type) {
 	case DATA_TYPE_IMAGETTE:
@@ -509,7 +451,7 @@ size_t generate_random_collection(struct collection_hdr *col, enum cmp_data_type
 	case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE:
 	case DATA_TYPE_F_CAM_IMAGETTE:
 	case DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE:
-		size += gen_ima_data(science_data, samples, max_used_bits);
+		size += gen_ima_data(science_data, data_type, samples, max_used_bits);
 		break;
 	case DATA_TYPE_OFFSET:
 		size += gen_nc_offset_data(science_data, samples, max_used_bits);
@@ -575,11 +517,25 @@ struct chunk_def {
 };
 
 
-static size_t generate_random_chunk(void *chunk, struct chunk_def col_array[], size_t array_elements,
+/**
+ * @brief generates a random chunk of collections
+ *
+ * @param chunk		pointer to  where the random chunk will be stored; if
+ *			NULL, the function will only return the size of the
+ *			random chunk
+ * @param col_array	specifies which collections are contained in the chunk
+ * @param array_elements	number of elements in the col_array
+ * @param max_used_bits	pointer to a structure that tracks the maximum number of
+ *			bits used
+ *
+ * @return the size of the generated random chunk in bytes
+ */
+
+static uint32_t generate_random_chunk(void *chunk, struct chunk_def col_array[], size_t array_elements,
 				    const struct cmp_max_used_bits *max_used_bits)
 {
 	size_t i;
-	size_t chunk_size = 0;
+	uint32_t chunk_size = 0;
 	struct collection_hdr *col = NULL;
 
 	for (i = 0; i < array_elements; i++) {
@@ -599,7 +555,7 @@ static size_t generate_random_chunk(void *chunk, struct chunk_def col_array[], s
  * @param cfg	pointer to a compression configuration
  */
 
-void generate_random_cmp_par(struct cmp_cfg *cfg)
+void generate_random_cmp_cfg(struct cmp_cfg *cfg)
 {
 	if (cmp_imagette_data_type_is_used(cfg->data_type)) {
 		cfg->cmp_par_imagette = cmp_rand_between(MIN_IMA_GOLOMB_PAR, MAX_IMA_GOLOMB_PAR);
@@ -644,6 +600,56 @@ void generate_random_cmp_par(struct cmp_cfg *cfg)
 }
 
 
+/**
+ * @brief generate random chunk compression parameters
+ *
+ * @param par	pointer where to store the chunk compression
+ */
+
+void generate_random_cmp_par(struct cmp_par *par)
+{
+	if (par) {
+		par->cmp_mode = cmp_rand_between(0, MAX_RDCU_CMP_MODE);
+		par->model_value = cmp_rand_between(0, MAX_MODEL_VALUE);
+		par->lossy_par = cmp_rand_between(0, MAX_ICU_ROUND);
+
+		par->nc_imagette = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+
+		par->s_exp_flags = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->s_fx = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->s_ncob = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->s_efx = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->s_ecob = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+
+		par->l_exp_flags = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->l_fx = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->l_ncob = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->l_efx = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->l_ecob = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->l_fx_cob_variance = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+
+		par->saturated_imagette = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+
+		par->nc_offset_mean = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->nc_offset_variance = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->nc_background_mean = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->nc_background_variance = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->nc_background_outlier_pixels = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+
+		par->smearing_mean = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->smearing_variance_mean = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->smearing_outlier_pixels = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+
+		par->fc_imagette = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->fc_offset_mean = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->fc_offset_variance = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->fc_background_mean = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->fc_background_variance = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+		par->fc_background_outlier_pixels = cmp_rand_between(MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
+	}
+}
+
+
 /**
  * @brief compress the given configuration and decompress it afterwards; finally
  *	compare the results
@@ -673,7 +679,7 @@ void compression_decompression(struct cmp_cfg *cfg)
 
 	/* create a compression entity */
 	cmp_data_size = cmp_cal_size_of_data(cfg->buffer_length, cfg->data_type);
-	cmp_data_size &= ~0x3U; /* the size of the compressed data should be a multiple of 4 */
+	/* cmp_data_size &= ~0x3U; /1* the size of the compressed data should be a multiple of 4 *1/ */
 	TEST_ASSERT_NOT_EQUAL_INT(0, cmp_data_size);
 
 	cmp_ent_size = cmp_ent_create(NULL, cfg->data_type, cfg->cmp_mode == CMP_MODE_RAW, cmp_data_size);
@@ -682,12 +688,13 @@ void compression_decompression(struct cmp_cfg *cfg)
 	cmp_ent_size = cmp_ent_create(ent, cfg->data_type, cfg->cmp_mode == CMP_MODE_RAW, cmp_data_size);
 	TEST_ASSERT_NOT_EQUAL_UINT(0, cmp_ent_size);
 
-	/* we put the coompressed data direct into the compression entity */
+	/* we put the compressed data direct into the compression entity */
 	cfg->icu_output_buf = cmp_ent_get_data_buf(ent);
 	TEST_ASSERT_NOT_NULL(cfg->icu_output_buf);
 
 	/* now compress the data */
 	cmp_size_bits = icu_compress_data(cfg);
+
 	TEST_ASSERT(cmp_size_bits > 0);
 
 	/* put the compression parameters in the entity header */
@@ -741,26 +748,27 @@ void compression_decompression(struct cmp_cfg *cfg)
 }
 
 
-#define CMP_BUFFER_FAKTOR 3 /* compression data buffer size / data to compress buffer size */
-
 /**
- * @brief random compression decompression test
- * @details We generate random data and compress them with random parameters.
- *	After that we put the data in a compression entity. We decompress the
- *	compression entity and compare the decompressed data with the original
- *	data.
+ * @brief random RDCU like compression decompression test
+ *
+ * We generate random imagette data and compress them with random parameters.
+ * After that we put the data in a compression entity. We decompress the
+ * compression entity and compare the decompressed data with the original data.
+ *
  * @test icu_compress_data
  * @test decompress_cmp_entiy
  */
 
-#define MB *(1U<<20)
-#define MAX_DATA_TO_COMPRESS_SIZE 0x1000B
-void test_random_compression_decompression(void)
+void test_random_round_trip_like_rdcu_compression(void)
 {
 	enum cmp_data_type data_type;
 	enum cmp_mode cmp_mode;
 	struct cmp_cfg cfg;
 	uint32_t cmp_buffer_size;
+	enum {
+		MAX_DATA_TO_COMPRESS_SIZE = 0x1000B,
+		CMP_BUFFER_FAKTOR = 3 /* compression data buffer size / data to compress buffer size */
+	};
 	void *data_to_compress1 = malloc(MAX_DATA_TO_COMPRESS_SIZE);
 	void *data_to_compress2 = malloc(MAX_DATA_TO_COMPRESS_SIZE);
 	void *updated_model = calloc(1, MAX_DATA_TO_COMPRESS_SIZE);
@@ -768,22 +776,19 @@ void test_random_compression_decompression(void)
 	for (data_type = 1; data_type <= DATA_TYPE_F_CAM_BACKGROUND; data_type++) {
 		/* printf("%s\n", data_type2string(data_type)); */
 		/* generate random data*/
-		/* uint32_t samples = cmp_rand_between(1, 430179/CMP_BUFFER_FAKTOR); */
 		size_t size;
 		uint32_t samples = cmp_rand_between(1, UINT16_MAX/size_of_a_sample(data_type));
 		uint32_t model_value = cmp_rand_between(0, MAX_MODEL_VALUE);
-		/* void *data_to_compress1 = generate_random_test_data(samples, data_type, &MAX_USED_BITS_V1); */
-		/* void *data_to_compress2 = generate_random_test_data(samples, data_type, &MAX_USED_BITS_V1); */
-		/* void *updated_model = calloc(1, cmp_cal_size_of_data(samples, data_type)); */
-		/* memset(updated_model, 0, MAX_DATA_TO_COMPRESS_SIZE); */
 
-		size = generate_random_collection(NULL, data_type, samples, &MAX_USED_BITS_V1);
+		if (!rdcu_supported_data_type_is_used(data_type))
+			continue;
+
+		size = gen_ima_data(NULL, data_type, samples, &MAX_USED_BITS_V1);
 		TEST_ASSERT(size <= MAX_DATA_TO_COMPRESS_SIZE);
-		size = generate_random_collection(data_to_compress1, data_type, samples, &MAX_USED_BITS_V1);
+		size = gen_ima_data(data_to_compress1, data_type, samples, &MAX_USED_BITS_V1);
 		TEST_ASSERT(size <= MAX_DATA_TO_COMPRESS_SIZE);
-		size = generate_random_collection(data_to_compress2, data_type, samples, &MAX_USED_BITS_V1);
+		size = gen_ima_data(data_to_compress2, data_type, samples, &MAX_USED_BITS_V1);
 		TEST_ASSERT(size <= MAX_DATA_TO_COMPRESS_SIZE);
-
 		/* for (cmp_mode = CMP_MODE_RAW; cmp_mode <= CMP_MODE_STUFF; cmp_mode++) { */
 		for (cmp_mode = CMP_MODE_RAW; cmp_mode <= CMP_MODE_DIFF_MULTI; cmp_mode++) {
 			/* printf("cmp_mode: %i\n", cmp_mode); */
@@ -791,14 +796,14 @@ void test_random_compression_decompression(void)
 						 CMP_LOSSLESS);
 			TEST_ASSERT_NOT_EQUAL_INT(cfg.data_type, DATA_TYPE_UNKNOWN);
 
-			generate_random_cmp_par(&cfg);
+			generate_random_cmp_cfg(&cfg);
 
 			if (!model_mode_is_used(cmp_mode))
 				cmp_buffer_size = cmp_cfg_icu_buffers(&cfg, data_to_compress1,
-					samples, NULL, NULL, NULL, samples*CMP_BUFFER_FAKTOR);
+								      samples, NULL, NULL, NULL, samples*CMP_BUFFER_FAKTOR);
 			else
 				cmp_buffer_size = cmp_cfg_icu_buffers(&cfg, data_to_compress2,
-					samples, data_to_compress1, updated_model, NULL, samples*CMP_BUFFER_FAKTOR);
+								      samples, data_to_compress1, updated_model, NULL, samples*CMP_BUFFER_FAKTOR);
 
 			TEST_ASSERT_EQUAL_UINT(cmp_buffer_size, cmp_cal_size_of_data(CMP_BUFFER_FAKTOR*samples, data_type));
 
@@ -812,8 +817,11 @@ void test_random_compression_decompression(void)
 }
 
 
-#define N_SAMPLES 5
-void test_random_compression_decompression2(void)
+/**
+ * @test icu_compress_data
+ */
+
+void test_random_compression_decompress_rdcu_data(void)
 {
 	struct cmp_cfg cfg;
 	struct cmp_info info = {0};
@@ -821,7 +829,11 @@ void test_random_compression_decompression2(void)
 	int s, i, cmp_size_bits;
 	void *compressed_data;
 	uint16_t *decompressed_data;
+	enum {N_SAMPLES = 5};
 	uint16_t data[N_SAMPLES] = {0, UINT16_MAX, INT16_MAX, 42, 23};
+	enum {
+		CMP_BUFFER_FAKTOR = 2 /* compression data buffer size / data to compress buffer size */
+	};
 
 	cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_RAW, 8, CMP_LOSSLESS);
 	TEST_ASSERT_NOT_EQUAL_INT(cfg.data_type, DATA_TYPE_UNKNOWN);
@@ -846,173 +858,204 @@ void test_random_compression_decompression2(void)
 	info.rdcu_cmp_adr_used = cfg.rdcu_buffer_adr;
 
 	s = decompress_rdcu_data(compressed_data, &info, NULL, NULL, NULL);
-	TEST_ASSERT(s > 0);
+	TEST_ASSERT_EQUAL(sizeof(data), s);
 	decompressed_data = malloc((size_t)s);
 	s = decompress_rdcu_data(compressed_data, &info, NULL, NULL, decompressed_data);
-	TEST_ASSERT(s > 0);
+	TEST_ASSERT_EQUAL(sizeof(data), s);
 
 	for (i = 0; i < N_SAMPLES; i++)
 		TEST_ASSERT_EQUAL_HEX16(data[i], decompressed_data[i]);
 
-
 	free(compressed_data);
 	free(decompressed_data);
 }
 
-#if 0
-int icu_compress_chunk(void *chunk, size_t chunk_size, void *model, void *dst,
-		       size_t dst_capacity);
-void no_test_chunk(void)
+
+static int32_t chunk_round_trip(void *data, uint32_t data_size,
+			       void *model, void *up_model,
+			       uint32_t *cmp_data, uint32_t cmp_data_capacity,
+			       struct cmp_par *cmp_par, int use_decmp_buf, int use_decmp_up_model)
 {
-	size_t s, i;
-	struct todo chunk_struct[3];
-	uint8_t *buf;
-	uint8_t *dst;
-
-	cmp_rand_seed(0);
-	chunk_struct[0].data_type = DATA_TYPE_F_FX;
-	chunk_struct[0].samples = 10;
-
-	chunk_struct[1].data_type = DATA_TYPE_S_FX;
-	chunk_struct[1].samples = 3;
-
-	chunk_struct[2].data_type = DATA_TYPE_SMEARING;
-	chunk_struct[2].samples = 4;
-
-	s = generate_random_chunk(NULL, chunk_struct, ARRAY_SIZE(chunk_struct), &MAX_USED_BITS_V1);
-	printf("s: %zu\n", s);
-
-	buf = malloc(s);
-	s = generate_random_chunk(buf, chunk_struct, ARRAY_SIZE(chunk_struct), &MAX_USED_BITS_V1);
-	printf("data to compress (s: %zu)\n", s);
-	for (i = 0; i < s; ++i) {
-		printf("%02X", buf[i]);
-		if ((i + 1) % 2 == 0)
-			printf("\n");
+	int32_t cmp_size;
+	void *model_cpy = NULL;
+
+	/* if in-place model update is used (up_model == model), the model
+	 * needed for decompression is destroyed; therefore we make a copy
+	 */
+	if (model) {
+		if (up_model == model) {
+			model_cpy = cmp_test_malloc(data_size);
+			memcpy(model_cpy, model, data_size);
+		} else {
+			model_cpy = model;
+		}
 	}
 
-	dst = malloc(s+1000);
-	s = icu_compress_chunk(buf, s, NULL, dst, s+1000);
-	printf("\n\ncompressed data (s: %zu)\n", s);
-	for (i = 0; i < s; ++i) {
-		printf("%02X", dst[i]);
-		if ((i + 1) % 2 == 0)
-			printf("\n");
-	}
+	cmp_size = compress_chunk(data, data_size, model, up_model,
+				  cmp_data, cmp_data_capacity, cmp_par);
+	TEST_ASSERT(cmp_size != CMP_ERROR_HIGH_VALUE);
 
-	free(dst);
-	free(buf);
-}
+#if 0
+	{ /* Compress a second time and check for determinism */
+		int32_t cSize2;
+		void *compressed2 = NULL;
+		void *up_model2 = NULL;
+
+		if (compressed)
+			compressed2 = FUZZ_malloc(compressedCapacity);
+
+		if (up_model)
+			up_model2 = FUZZ_malloc(srcSize);
+		cSize2 = compress_chunk((void *)src, srcSize, (void *)model, up_model2,
+					   compressed2, compressedCapacity, cmp_par);
+		FUZZ_ASSERT(cSize == cSize2);
+		FUZZ_ASSERT_MSG(!FUZZ_memcmp(compressed, compressed2, cSize), "Not deterministic!");
+		FUZZ_ASSERT_MSG(!FUZZ_memcmp(up_model, compressed2, cSize), "NO deterministic!");
+		free(compressed2);
+		free(up_model2);
+	}
 #endif
-#include <byteorder.h>
+	if (cmp_size >= 0 && cmp_data) {
+		void *decmp_data = NULL;
+		void *up_model_decmp = NULL;
+		int decmp_size;
+
+		decmp_size = decompress_cmp_entiy((struct cmp_entity *)cmp_data, model_cpy, NULL, NULL);
+		TEST_ASSERT(decmp_size >= 0);
+		TEST_ASSERT_EQUAL((uint32_t)decmp_size, data_size);
+
+		if (use_decmp_buf)
+			decmp_data = cmp_test_malloc(data_size);
+		if (use_decmp_up_model)
+			up_model_decmp = cmp_test_malloc(data_size);
+
+		decmp_size = decompress_cmp_entiy((struct cmp_entity *)cmp_data, model_cpy,
+						  up_model_decmp, decmp_data);
+		TEST_ASSERT(decmp_size >= 0);
+		TEST_ASSERT((uint32_t)decmp_size == data_size);
+
+		if (use_decmp_buf) {
+			TEST_ASSERT_EQUAL_HEX8_ARRAY(data, decmp_data, data_size);
+			TEST_ASSERT(!memcmp(data, decmp_data, data_size));
+
+			/*
+			 * the model is only updated when the decompressed_data
+			 * buffer is set
+			 */
+			if (up_model && up_model_decmp)
+				TEST_ASSERT(!memcmp(up_model, up_model_decmp, data_size));
+		}
 
-size_t set_cmp_size(uint8_t *p, uint16_t v)
-{
-	v -= COLLECTION_HDR_SIZE;
-	memset(p, v >> 8, 1);
-	memset(p+1, v & 0xFF, 1);
-	return sizeof(uint16_t);
-}
+		free(decmp_data);
+		free(up_model_decmp);
+	}
 
-uint16_t get_cmp_size(uint8_t *p)
-{
-	return ((uint16_t)p[0]<<8) + p[1];
+	if (up_model == model)
+		free(model_cpy);
+
+	return cmp_size;
 }
-#if 0
-remove this
-void no_test_new_format(void)
+
+
+/**
+ * @brief random compression decompression round trip test
+ *
+ * We generate random data and compress them with random parameters.
+ * We decompress the compression entity and compare the decompressed data with
+ * the original data.
+ *
+ * @test compress_chunk
+ * @test decompress_cmp_entiy
+ */
+
+
+void test_random_chunk_round_trip(void)
 {
-	uint32_t data_size = cmp_cal_size_of_data(3, DATA_TYPE_L_FX_EFX_NCOB_ECOB);
-	data_size += cmp_cal_size_of_data(2, DATA_TYPE_L_FX_EFX_NCOB_ECOB);
-	data_size += cmp_cal_size_of_data(5, DATA_TYPE_L_FX);
-	data_size += cmp_cal_size_of_data(2, DATA_TYPE_L_FX);
-	data_size += 3*sizeof(uint16_t);
-
-	uint32_t ent_size = cmp_ent_create(NULL, DATA_TYPE_L_FX, 1, data_size);
-	void *ent = calloc(1, ent_size);
-	ent_size = cmp_ent_create(ent, DATA_TYPE_L_FX, 1, data_size);
-
-	char *p = cmp_ent_get_data_buf(ent);
-	p +=2;
-	uint16_t s = generate_random_collection(p, DATA_TYPE_L_FX, 2, &MAX_USED_BITS_V1);
-	p += set_cmp_size(p-2, s);
-	p += s;
-	s = generate_random_collection(p, DATA_TYPE_L_FX, 5, &MAX_USED_BITS_V1);
-	p += set_cmp_size(p-2, s);
-	p += s;
-	s = generate_random_collection(p, DATA_TYPE_L_FX_EFX_NCOB_ECOB, 2, &MAX_USED_BITS_V1);
-	p += set_cmp_size(p-2, s);
-	p += s;
-	s = generate_random_collection(p, DATA_TYPE_L_FX_EFX_NCOB_ECOB, 2, &MAX_USED_BITS_V1);
-	p+=s;
-
-	int num_of_coll =4;
-
-	uint8_t *d_p = cmp_ent_get_data_buf(ent);
-	uint32_t sum =0;
-	s =0;
-	for (int c = 1; c <= num_of_coll ;  c++) {
-		uint16_t cmp_col_size;
-		if (c == num_of_coll)
-			cmp_col_size = cmp_ent_get_cmp_data_size(ent)- sum;
-		else{
-			cmp_col_size = get_cmp_size(&d_p[s]);
-			sum += cmp_col_size;
-			s+=2;
-		}
+	enum cmp_data_type data_type;
+	enum cmp_mode cmp_mode;
+	enum { MAX_DATA_TO_COMPRESS_SIZE = CMP_ENTITY_MAX_ORIGINAL_SIZE};
+	void *data = malloc(CMP_ENTITY_MAX_ORIGINAL_SIZE);
+	void *model = malloc(MAX_DATA_TO_COMPRESS_SIZE);
+	void *updated_model = calloc(1, MAX_DATA_TO_COMPRESS_SIZE);
+	uint32_t cmp_data_capacity = CMP_ENTITY_MAX_SIZE-NON_IMAGETTE_HEADER_SIZE;
+	void *cmp_data = malloc(cmp_data_capacity);
+
+	for (data_type = 1; data_type <= DATA_TYPE_F_CAM_BACKGROUND; data_type++) {
+		/* printf("%s\n", data_type2string(data_type)); */
+		/* generate random data*/
+		size_t size;
+		uint32_t samples = cmp_rand_between(1, UINT16_MAX/size_of_a_sample(data_type));
+
+		size = generate_random_collection(NULL, data_type, samples, &MAX_USED_BITS_SAFE);
+		TEST_ASSERT(size <= MAX_DATA_TO_COMPRESS_SIZE);
+		size = generate_random_collection(data, data_type, samples, &MAX_USED_BITS_SAFE);
+		TEST_ASSERT(size <= MAX_DATA_TO_COMPRESS_SIZE);
+		size = generate_random_collection(model, data_type, samples, &MAX_USED_BITS_SAFE);
+		TEST_ASSERT(size <= MAX_DATA_TO_COMPRESS_SIZE);
 
-		uint16_t col_size = cmp_col_get_data_length(&d_p[s]);
-		printf("cmp_col_sizel: %X col_size: %X\n", cmp_col_size, col_size);
-		for (int i = s-2; i < s+col_size +COLLECTION_HDR_SIZE; ++i) {
-			printf("%02X ",((uint8_t *)d_p)[i]);
-			if ((i + 1) % 2 == 0)
-				printf("\n");
+		for (cmp_mode = CMP_MODE_RAW; cmp_mode <= CMP_MODE_DIFF_MULTI; cmp_mode++) {
+			struct cmp_par par;
+			int32_t cmp_size;
+
+			generate_random_cmp_par(&par);
+			par.cmp_mode = cmp_mode;
+			par.lossy_par = CMP_LOSSLESS;
+
+			cmp_size = chunk_round_trip(data, (uint32_t)size, model, updated_model,
+						   cmp_data, cmp_data_capacity,
+						   &par, 1, model_mode_is_used(par.cmp_mode));
+			/* No chunk is defined for fast cadence subservices */
+			if (data_type == DATA_TYPE_F_FX || data_type == DATA_TYPE_F_FX_EFX ||
+			    data_type == DATA_TYPE_F_FX_NCOB || data_type == DATA_TYPE_F_FX_EFX_NCOB_ECOB)
+				TEST_ASSERT(cmp_size == -1);
+			else
+				TEST_ASSERT(cmp_size > 0);
 		}
-		TEST_ASSERT(cmp_col_size == col_size);
-		s+=col_size+COLLECTION_HDR_SIZE;
 	}
-
+	free(data);
+	free(model);
+	free(updated_model);
+	free(cmp_data);
 }
-#endif
-#if 0
-/* #include "../../lib/common/byteorder.h" */
-void NOOO_test_cmp_collection_raw(void)
+
+
+/**
+ * @test compress_chunk
+ * @test decompress_cmp_entiy
+ */
+
+void test_cmp_collection_raw(void)
 {
 	struct collection_hdr *col = NULL;
 	uint32_t samples = 2;
-	size_t col_size, dst_capacity = 0;
+	uint32_t dst_capacity = 0;
 	struct s_fx *data;
 	uint32_t *dst = NULL;
-	int dst_capacity_used = 0;
 	struct cmp_par par = {0};
-	const size_t exp_col_size = COLLECTION_HDR_SIZE+2*sizeof(struct s_fx);
-	const size_t exp_cmp_size_byte = exp_col_size;
+	const uint32_t col_size = COLLECTION_HDR_SIZE+2*sizeof(struct s_fx);
+	const size_t exp_cmp_size_byte = GENERIC_HEADER_SIZE + col_size;
+	int cmp_size_byte;
 
 	par.cmp_mode = CMP_MODE_RAW;
 
-	col_size = generate_random_collection(col, DATA_TYPE_S_FX, samples, &MAX_USED_BITS_SAFE);
-	TEST_ASSERT_EQUAL(exp_col_size, col_size);
-	col = malloc(col_size);
-	TEST_ASSERT_NOT_NULL(col);
-	col_size = generate_random_collection(col, DATA_TYPE_S_FX, samples, &MAX_USED_BITS_SAFE);
-	TEST_ASSERT_EQUAL(exp_col_size, col_size);
-
+	col = malloc(col_size); TEST_ASSERT_NOT_NULL(col);
+	generate_random_collection_hdr(col, DATA_TYPE_S_FX, samples);
 	data = (struct s_fx *)col->entry;
 	data[0].exp_flags = 0;
 	data[0].fx = 0;
 	data[1].exp_flags = 0xF0;
 	data[1].fx = 0xABCDE0FF;
 
-
-	dst_capacity = (size_t)cmp_collection(col, NULL, dst, dst_capacity, &par, dst_capacity_used);
-	TEST_ASSERT_EQUAL_INT(exp_cmp_size_byte, dst_capacity);
+	cmp_size_byte = compress_chunk(col, col_size, NULL, NULL, dst, dst_capacity, &par);
+	TEST_ASSERT_EQUAL_INT(exp_cmp_size_byte, cmp_size_byte);
+	dst_capacity = (uint32_t)cmp_size_byte;
 	dst = malloc(dst_capacity);
 	TEST_ASSERT_NOT_NULL(dst);
-	dst_capacity_used = cmp_collection(col, NULL, dst, dst_capacity, &par, dst_capacity_used);
-	TEST_ASSERT_EQUAL_INT(exp_cmp_size_byte, dst_capacity_used);
+	cmp_size_byte = compress_chunk(col, col_size, NULL, NULL, dst, dst_capacity, &par);
+	TEST_ASSERT_EQUAL_INT(exp_cmp_size_byte, cmp_size_byte);
 
 	{
-		uint8_t *p = (uint8_t *)dst;
+		uint8_t *p = (uint8_t *)dst+GENERIC_HEADER_SIZE;
 		struct collection_hdr *raw_cmp_col = (struct collection_hdr *)p;
 		struct s_fx *raw_cmp_data = (void *)raw_cmp_col->entry;
 
@@ -1023,62 +1066,69 @@ void NOOO_test_cmp_collection_raw(void)
 		TEST_ASSERT_EQUAL_HEX(data[1].exp_flags, raw_cmp_data[1].exp_flags);
 		TEST_ASSERT_EQUAL_HEX(data[1].fx, be32_to_cpu(raw_cmp_data[1].fx));
 	}
+	{ /* decompress the data */
+		int decmp_size;
+		uint8_t *decompressed_data;
+
+		decmp_size = decompress_cmp_entiy((struct cmp_entity *)dst, NULL, NULL, NULL);
+		TEST_ASSERT_EQUAL_INT(col_size, decmp_size);
+		decompressed_data = malloc((size_t)decmp_size); TEST_ASSERT_TRUE(decompressed_data);
+		decmp_size = decompress_cmp_entiy((struct cmp_entity *)dst, NULL, NULL, decompressed_data);
+		TEST_ASSERT_EQUAL_INT(col_size, decmp_size);
+		TEST_ASSERT_EQUAL_HEX8_ARRAY(col, decompressed_data, decmp_size);
+		free(decompressed_data);
+	}
 
-	memset(dst, 0, dst_capacity);
-
+	/* error case: buffer for the compressed data is to small */
 	dst_capacity -= 1;
-	dst_capacity_used = cmp_collection(col, NULL, dst, dst_capacity, &par, dst_capacity_used);
-	TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, dst_capacity_used);
+	TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, compress_chunk(col, col_size, NULL, NULL, dst, dst_capacity, &par));
 
 	free(col);
 	free(dst);
 }
 
 
-void NOOO_test_cmp_collection_diff(void)
+/**
+ * @test compress_chunk
+ * @test decompress_cmp_entiy
+ */
+
+void test_cmp_collection_diff(void)
 {
 	struct collection_hdr *col = NULL;
 	uint32_t *dst = NULL;
-	size_t dst_capacity = 0;
-	int dst_capacity_used = 33;
+	uint32_t dst_capacity = 0;
 	struct cmp_par par = {0};
-	const uint16_t cmp_size_byte_exp= 2;
+	const uint16_t cmp_size_byte_exp = 2;
+	struct s_fx *data;
+	const uint32_t samples = 2;
+	const uint32_t col_size = COLLECTION_HDR_SIZE+samples*sizeof(*data);
 
 
-	{ /* generate test data */
-		struct s_fx *data;
-		uint32_t samples = 2;
-		size_t col_size;
-		const size_t exp_col_size = COLLECTION_HDR_SIZE+samples*sizeof(*data);
+	 /* generate test data */
+	col = malloc(col_size); TEST_ASSERT_NOT_NULL(col);
+	generate_random_collection_hdr(col, DATA_TYPE_S_FX, samples);
+	data = (struct s_fx *)col->entry;
+	data[0].exp_flags = 0;
+	data[0].fx = 0;
+	data[1].exp_flags = 1;
+	data[1].fx = 1;
 
-		col_size = generate_random_collection(col, DATA_TYPE_S_FX, samples, &MAX_USED_BITS_SAFE);
-		TEST_ASSERT_EQUAL(exp_col_size, col_size);
-		col = malloc(col_size); TEST_ASSERT_NOT_NULL(col);
-		col_size = generate_random_collection(col, DATA_TYPE_S_FX, samples, &MAX_USED_BITS_SAFE);
-		TEST_ASSERT_EQUAL(exp_col_size, col_size);
-
-		data = (struct s_fx *)col->entry;
-		data[0].exp_flags = 0;
-		data[0].fx = 0;
-		data[1].exp_flags = 1;
-		data[1].fx = 1;
-	}
 
 	{ /* compress data */
 		int cmp_size_byte;
-		const int exp_cmp_size_byte = dst_capacity_used + CMP_COLLECTION_FILD_SIZE
-			+ COLLECTION_HDR_SIZE + cmp_size_byte_exp;;
+		const int exp_cmp_size_byte = NON_IMAGETTE_HEADER_SIZE + CMP_COLLECTION_FILD_SIZE
+			+ COLLECTION_HDR_SIZE + cmp_size_byte_exp;
 
 		par.cmp_mode = CMP_MODE_DIFF_ZERO;
 		par.s_exp_flags = 1;
 		par.s_fx = 1;
 
-		cmp_size_byte = cmp_collection(col, NULL, dst, dst_capacity, &par, dst_capacity_used);
+		cmp_size_byte = compress_chunk(col, col_size, NULL, NULL, dst, dst_capacity, &par);
 		TEST_ASSERT_EQUAL_INT(exp_cmp_size_byte, cmp_size_byte);
-		dst_capacity = (size_t)ROUND_UP_TO_MULTIPLE_OF_4(cmp_size_byte);
+		dst_capacity = (uint32_t)ROUND_UP_TO_MULTIPLE_OF_4(cmp_size_byte);
 		dst = malloc(dst_capacity); TEST_ASSERT_NOT_NULL(dst);
-		memset(dst, 0xFF, dst_capacity);
-		cmp_size_byte = cmp_collection(col, NULL, dst, dst_capacity, &par, dst_capacity_used);
+		cmp_size_byte = compress_chunk(col, col_size, NULL, NULL, dst, dst_capacity, &par);
 		TEST_ASSERT_EQUAL_INT(exp_cmp_size_byte, cmp_size_byte);
 	}
 
@@ -1086,8 +1136,8 @@ void NOOO_test_cmp_collection_diff(void)
 		uint8_t *p = (uint8_t *)dst;
 		uint16_t cmp_collection_size_exp = cpu_to_be16(cmp_size_byte_exp);
 
-		TEST_ASSERT_EACH_EQUAL_HEX8(0xFF, p, dst_capacity_used);
-		p += dst_capacity_used;
+		/* TODO: check the entity header */
+		p += NON_IMAGETTE_HEADER_SIZE;
 
 		TEST_ASSERT_EQUAL_HEX8_ARRAY(&cmp_collection_size_exp, p, CMP_COLLECTION_FILD_SIZE);
 		p += CMP_COLLECTION_FILD_SIZE;
@@ -1097,68 +1147,72 @@ void NOOO_test_cmp_collection_diff(void)
 
 		TEST_ASSERT_EQUAL_HEX8(0xAE, *p++);
 		TEST_ASSERT_EQUAL_HEX8(0xE0, *p++);
-		TEST_ASSERT_EQUAL_HEX8(0x00, *p++);
-		TEST_ASSERT_EQUAL_HEX8(0x00, *p++);
-		TEST_ASSERT_EQUAL_HEX8(0x00, *p++);
 
 		TEST_ASSERT_EQUAL_size_t(dst_capacity, p - (uint8_t *)dst);
 	}
-
+	{ /* decompress the data */
+		int decmp_size;
+		uint8_t *decompressed_data;
+
+		decmp_size = decompress_cmp_entiy((struct cmp_entity *)dst, NULL, NULL, NULL);
+		TEST_ASSERT_EQUAL_INT(col_size, decmp_size);
+		decompressed_data = malloc((size_t)decmp_size); TEST_ASSERT_TRUE(decompressed_data);
+		decmp_size = decompress_cmp_entiy((struct cmp_entity *)dst, NULL, NULL, decompressed_data);
+		TEST_ASSERT_EQUAL_INT(col_size, decmp_size);
+		TEST_ASSERT_EQUAL_HEX8_ARRAY(col, decompressed_data, decmp_size);
+		free(decompressed_data);
+	}
 
 	/* error cases dst buffer to small */
 	dst_capacity -= 1;
-	dst_capacity_used = cmp_collection(col, NULL, dst, dst_capacity, &par, dst_capacity_used);
-	TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, dst_capacity_used);
+	TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, compress_chunk(col, col_size, NULL, NULL, dst, dst_capacity, &par));
 
 	free(col);
 	free(dst);
 }
 
 
-void NOOO_test_cmp_collection_worst_case(void)
+/**
+ * @test compress_chunk
+ * @test decompress_cmp_entiy
+ */
+
+void test_cmp_collection_worst_case(void)
 {
 	struct collection_hdr *col = NULL;
 	uint32_t *dst = NULL;
-	size_t dst_capacity = 0;
-	int dst_capacity_used = 4;
+	uint32_t dst_capacity = 0;
 	struct cmp_par par = {0};
-	const uint16_t cmp_size_byte_exp= 2*sizeof(struct s_fx);
+	const uint16_t cmp_size_byte_exp = 2*sizeof(struct s_fx);
 	int cmp_size_byte;
+	struct s_fx *data;
+	uint32_t samples = 2;
+	const uint32_t col_size = COLLECTION_HDR_SIZE+samples*sizeof(*data);
 
-	{ /* generate test data */
-		struct s_fx *data;
-		uint32_t samples = 2;
-		size_t col_size;
-		const size_t exp_col_size = COLLECTION_HDR_SIZE+samples*sizeof(*data);
+	/* generate test data */
+	col = malloc(col_size); TEST_ASSERT_NOT_NULL(col);
+	generate_random_collection_hdr(col, DATA_TYPE_S_FX, samples);
+	data = (struct s_fx *)col->entry;
+	data[0].exp_flags = 0x4;
+	data[0].fx = 0x0000000E;
+	data[1].exp_flags = 0x4;
+	data[1].fx = 0x00000016;
 
-		col_size = generate_random_collection(col, DATA_TYPE_S_FX, samples, &MAX_USED_BITS_SAFE);
-		TEST_ASSERT_EQUAL(exp_col_size, col_size);
-		col = malloc(col_size); TEST_ASSERT_NOT_NULL(col);
-		col_size = generate_random_collection(col, DATA_TYPE_S_FX, samples, &MAX_USED_BITS_SAFE);
-		TEST_ASSERT_EQUAL(exp_col_size, col_size);
-
-		data = (struct s_fx *)col->entry;
-		data[0].exp_flags = 0x4;
-		data[0].fx = 0x0000000E;
-		data[1].exp_flags = 0x4;
-		data[1].fx = 0x00000016;
-;
-	}
 
 	{ /* compress data */
-		const int exp_cmp_size_byte = dst_capacity_used + CMP_COLLECTION_FILD_SIZE
-			+ COLLECTION_HDR_SIZE + cmp_size_byte_exp;;
+		const int exp_cmp_size_byte = NON_IMAGETTE_HEADER_SIZE + CMP_COLLECTION_FILD_SIZE
+			+ COLLECTION_HDR_SIZE + cmp_size_byte_exp;
 
 		par.cmp_mode = CMP_MODE_DIFF_ZERO;
 		par.s_exp_flags = 1;
 		par.s_fx = 1;
 
-		cmp_size_byte = cmp_collection(col, NULL, dst, dst_capacity, &par, dst_capacity_used);
+		cmp_size_byte = compress_chunk(col, col_size, NULL, NULL, dst, dst_capacity, &par);
 		TEST_ASSERT_EQUAL_INT(exp_cmp_size_byte, cmp_size_byte);
-		dst_capacity = 1000;
+		dst_capacity = (uint32_t)cmp_size_byte;
 		dst = malloc(dst_capacity); TEST_ASSERT_NOT_NULL(dst);
 		memset(dst, 0xFF, dst_capacity);
-		cmp_size_byte = cmp_collection(col, NULL, dst, dst_capacity, &par, dst_capacity_used);
+		cmp_size_byte = compress_chunk(col, col_size, NULL, NULL, dst, dst_capacity, &par);
 		TEST_ASSERT_EQUAL_INT(exp_cmp_size_byte, cmp_size_byte);
 	}
 
@@ -1166,8 +1220,8 @@ void NOOO_test_cmp_collection_worst_case(void)
 		uint8_t *p = (uint8_t *)dst;
 		uint16_t cmp_collection_size_exp = cpu_to_be16(cmp_size_byte_exp);
 
-		TEST_ASSERT_EACH_EQUAL_HEX8(0xFF, p, dst_capacity_used);
-		p += dst_capacity_used;
+		/* TODO: check the entity header */
+		p += NON_IMAGETTE_HEADER_SIZE;
 
 		TEST_ASSERT_EQUAL_HEX8_ARRAY(&cmp_collection_size_exp, p, CMP_COLLECTION_FILD_SIZE);
 		p += CMP_COLLECTION_FILD_SIZE;
@@ -1188,19 +1242,121 @@ void NOOO_test_cmp_collection_worst_case(void)
 
 		TEST_ASSERT_EQUAL_size_t(cmp_size_byte, p - (uint8_t *)dst);
 	}
+	{ /* decompress the data */
+		int decmp_size;
+		uint8_t *decompressed_data;
+
+		decmp_size = decompress_cmp_entiy((struct cmp_entity *)dst, NULL, NULL, NULL);
+		TEST_ASSERT_EQUAL_INT(col_size, decmp_size);
+		decompressed_data = malloc((size_t)decmp_size); TEST_ASSERT_TRUE(decompressed_data);
+		decmp_size = decompress_cmp_entiy((struct cmp_entity *)dst, NULL, NULL, decompressed_data);
+		TEST_ASSERT_EQUAL_INT(col_size, decmp_size);
+		TEST_ASSERT_EQUAL_HEX8_ARRAY(col, decompressed_data, decmp_size);
+		free(decompressed_data);
+	}
+	free(dst);
+	free(col);
 }
-#endif
 
 
-void test_cmp_chunk_raw2(void)
+/**
+ * @test compress_chunk
+ * @test decompress_cmp_entiy
+ */
+
+void test_cmp_collection_imagette_worst_case(void)
+{
+	struct collection_hdr *col = NULL;
+	uint32_t *dst = NULL;
+	struct cmp_par par = {0};
+	uint16_t const cmp_size_byte_exp = 10*sizeof(uint16_t);
+	int cmp_size_byte;
+	uint32_t const col_size = COLLECTION_HDR_SIZE + cmp_size_byte_exp;
+
+	{ /* generate test data */
+		uint16_t *data;
+
+		col = malloc(col_size); TEST_ASSERT_NOT_NULL(col);
+		generate_random_collection_hdr(col, DATA_TYPE_IMAGETTE, 10);
+
+		data = (void *)col->entry;
+		data[0] = 0x0102;
+		data[1] = 0x0304;
+		data[2] = 0x0506;
+		data[3] = 0x0708;
+		data[4] = 0x090A;
+		data[5] = 0x0B0C;
+		data[6] = 0x0D0E;
+		data[7] = 0x0F10;
+		data[8] = 0x1112;
+		data[9] = 0x1314;
+	}
+
+	{ /* compress data */
+		uint32_t dst_capacity = 0;
+		const int exp_cmp_size_byte = NON_IMAGETTE_HEADER_SIZE + CMP_COLLECTION_FILD_SIZE
+			+ COLLECTION_HDR_SIZE + cmp_size_byte_exp;
+
+		par.cmp_mode = CMP_MODE_DIFF_MULTI;
+		par.nc_imagette = 62;
+
+		cmp_size_byte = compress_chunk(col, col_size, NULL, NULL, dst, dst_capacity, &par);
+		TEST_ASSERT_EQUAL_INT(exp_cmp_size_byte, cmp_size_byte);
+		dst_capacity = (uint32_t)cmp_size_byte;
+		dst = malloc(dst_capacity); TEST_ASSERT_NOT_NULL(dst);
+		memset(dst, 0xFF, dst_capacity);
+		cmp_size_byte = compress_chunk(col, col_size, NULL, NULL, dst, dst_capacity, &par);
+		TEST_ASSERT_EQUAL_INT(exp_cmp_size_byte, cmp_size_byte);
+	}
+
+	{ /* check the compressed data */
+		uint32_t i;
+		uint8_t *p = (uint8_t *)dst;
+		uint16_t cmp_collection_size_exp = cpu_to_be16(cmp_size_byte_exp);
+
+		/* TODO: check the entity header */
+		p += NON_IMAGETTE_HEADER_SIZE;
+
+		TEST_ASSERT_EQUAL_HEX8_ARRAY(&cmp_collection_size_exp, p, CMP_COLLECTION_FILD_SIZE);
+		p += CMP_COLLECTION_FILD_SIZE;
+
+		TEST_ASSERT(memcmp(col, p, COLLECTION_HDR_SIZE) == 0);
+		p += COLLECTION_HDR_SIZE;
+
+		for (i = 1; i <= col_size-COLLECTION_HDR_SIZE; ++i)
+			TEST_ASSERT_EQUAL_HEX8(i, *p++);
+
+		TEST_ASSERT_EQUAL_size_t(cmp_size_byte, p - (uint8_t *)dst);
+	}
+	{ /* decompress the data */
+		int decmp_size;
+		uint8_t *decompressed_data;
+
+		decmp_size = decompress_cmp_entiy((struct cmp_entity *)dst, NULL, NULL, NULL);
+		TEST_ASSERT_EQUAL_INT(col_size, decmp_size);
+		decompressed_data = malloc((size_t)decmp_size); TEST_ASSERT_TRUE(decompressed_data);
+		decmp_size = decompress_cmp_entiy((struct cmp_entity *)dst, NULL, NULL, decompressed_data);
+		TEST_ASSERT_EQUAL_INT(col_size, decmp_size);
+		TEST_ASSERT_EQUAL_HEX8_ARRAY(col, decompressed_data, decmp_size);
+		free(decompressed_data);
+	}
+}
+
+
+/**
+ * @test compress_chunk
+ * @test decompress_cmp_entiy
+ */
+
+void test_cmp_decmp_chunk_raw(void)
 {
 	struct cmp_par par = {0};
 	struct chunk_def chunk_def[2] = {{DATA_TYPE_S_FX, 2}, {DATA_TYPE_S_FX_EFX_NCOB_ECOB, 3}};
-	size_t chunk_size;
+	uint32_t chunk_size;
 	size_t chunk_size_exp = 2*sizeof(struct s_fx) + 3*sizeof(struct s_fx_efx_ncob_ecob) + 2*COLLECTION_HDR_SIZE;
 	void *chunk = NULL;
 	uint32_t *dst = NULL;
-	int dst_capacity = 0;
+	uint32_t dst_capacity = 0;
 
 	/* generate test data */
 	chunk_size = generate_random_chunk(chunk, chunk_def, ARRAY_SIZE(chunk_def), &MAX_USED_BITS_SAFE);
@@ -1212,37 +1368,33 @@ void test_cmp_chunk_raw2(void)
 
 	/* "compress" data */
 	{
-		size_t cmp_size_byte_exp = GENERIC_HEADER_SIZE + chunk_size_exp;
+		size_t cmp_size_exp = GENERIC_HEADER_SIZE + chunk_size_exp;
+		int cmp_size;
 
 		par.cmp_mode = CMP_MODE_RAW;
 
-		dst_capacity = compress_chunk(chunk, chunk_size, NULL, NULL, dst, dst_capacity, &par);
-		TEST_ASSERT_EQUAL_INT(cmp_size_byte_exp, dst_capacity);
-		dst = calloc(1, dst_capacity);
-		TEST_ASSERT_NOT_NULL(dst);
-		dst_capacity = compress_chunk(chunk, chunk_size, NULL, NULL, dst, dst_capacity, &par);
-		TEST_ASSERT_EQUAL_INT(cmp_size_byte_exp, dst_capacity);
+		cmp_size = compress_chunk(chunk, chunk_size, NULL, NULL, dst, dst_capacity, &par);
+		TEST_ASSERT_EQUAL_INT(cmp_size_exp, cmp_size);
+		dst_capacity = (uint32_t)cmp_size;
+		dst = malloc(dst_capacity); TEST_ASSERT_NOT_NULL(dst);
+		cmp_size = compress_chunk(chunk, chunk_size, NULL, NULL, dst, dst_capacity, &par);
+		TEST_ASSERT_EQUAL_INT(cmp_size_exp, dst_capacity);
 	}
 
 	/* check results */
 	{
 		uint8_t *p = (uint8_t *)dst;
-		/* uint16_t cmp_collection_size_exp = cpu_to_be16(2*sizeof(struct s_fx)); */
 		struct collection_hdr *col = (struct collection_hdr *)chunk;
 		struct s_fx *cmp_data_raw_1;
 		struct s_fx *data = (void *)col->entry;
 		int i;
 
-		/* TODO: Check header */
-		TEST_ASSERT_EQUAL_HEX(chunk_size, cmp_ent_get_original_size(dst));
-		TEST_ASSERT_EQUAL_HEX(chunk_size+GENERIC_HEADER_SIZE, cmp_ent_get_size(dst));
+		/* TODO: Check entity header */
+		TEST_ASSERT_EQUAL_HEX(chunk_size, cmp_ent_get_original_size((struct cmp_entity *)dst));
+		TEST_ASSERT_EQUAL_HEX(chunk_size+GENERIC_HEADER_SIZE, cmp_ent_get_size((struct cmp_entity *)dst));
 
 		p += GENERIC_HEADER_SIZE;
 
-
-		/* TEST_ASSERT(memcmp(p, &cmp_collection_size_exp, CMP_COLLECTION_FILD_SIZE) == 0); */
-		/* p += CMP_COLLECTION_FILD_SIZE; */
-
 		TEST_ASSERT(memcmp(col, p, COLLECTION_HDR_SIZE) == 0);
 		p += COLLECTION_HDR_SIZE;
 
@@ -1254,10 +1406,6 @@ void test_cmp_chunk_raw2(void)
 		p += 2*sizeof(struct s_fx);
 
 		/* check 2nd collection */
-		/* cmp_collection_size_exp = cpu_to_be16(3*sizeof(struct s_fx_efx_ncob_ecob)); */
-		/* TEST_ASSERT(memcmp(p, &cmp_collection_size_exp, CMP_COLLECTION_FILD_SIZE) == 0); */
-		/* p += CMP_COLLECTION_FILD_SIZE; */
-
 		col = (struct collection_hdr *) ((char *)col + cmp_col_get_size(col));
 		TEST_ASSERT(memcmp(col, p, COLLECTION_HDR_SIZE) == 0);
 		p += COLLECTION_HDR_SIZE;
@@ -1279,20 +1427,21 @@ void test_cmp_chunk_raw2(void)
 		void *decompressed_data = NULL;
 		int decmp_size = decompress_cmp_entiy((void *)dst, NULL, NULL, decompressed_data);
 		TEST_ASSERT_EQUAL_size_t(chunk_size, decmp_size);
+
 		decompressed_data = malloc((size_t)decmp_size); TEST_ASSERT_NOT_NULL(decompressed_data);
 		decmp_size = decompress_cmp_entiy((void *)dst, NULL, NULL, decompressed_data);
 
 		TEST_ASSERT_EQUAL_INT(chunk_size, decmp_size);
 		TEST_ASSERT_EQUAL_HEX8_ARRAY(chunk, decompressed_data, chunk_size);
+		free(decompressed_data);
 	}
+	{ /* error case: buffer to small for compressed data */
+		int cmp_size;
 
-	/* error cases */
-	memset(dst, 0, dst_capacity);
-
-	/* buffer to small for compressed data */
-	dst_capacity -=1 ;
-	dst_capacity = compress_chunk(chunk, chunk_size, NULL, NULL, dst, dst_capacity, &par);
-	TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, dst_capacity);
+		dst_capacity -= 1;
+		cmp_size = compress_chunk(chunk, chunk_size, NULL, NULL, dst, dst_capacity, &par);
+		TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, cmp_size);
+	}
 
 	free(chunk);
 }
@@ -1316,8 +1465,8 @@ void test_cmp_decmp_chunk_worst_case(void)
 	chunk_size = (uint32_t)generate_random_chunk(chunk, chunk_def, ARRAY_SIZE(chunk_def), &MAX_USED_BITS_SAFE);
 	TEST_ASSERT_EQUAL_size_t(CHUNK_SIZE_EXP, chunk_size);
 
-	/* "compress" data */
-	{
+
+	{ /* "compress" data */
 		size_t cmp_size_byte_exp = NON_IMAGETTE_HEADER_SIZE + 2*CMP_COLLECTION_FILD_SIZE + CHUNK_SIZE_EXP;
 
 		par.cmp_mode = CMP_MODE_DIFF_ZERO;
@@ -1333,8 +1482,7 @@ void test_cmp_decmp_chunk_worst_case(void)
 		TEST_ASSERT_EQUAL_INT(cmp_size_byte_exp, cmp_size_byte);
 	}
 
-	/* check results */
-	{
+	{ /* check results */
 		uint8_t *p = (uint8_t *)dst;
 		uint16_t cmp_collection_size_exp = cpu_to_be16(2*sizeof(struct s_fx));
 		struct collection_hdr *col = (struct collection_hdr *)chunk;
@@ -1342,7 +1490,7 @@ void test_cmp_decmp_chunk_worst_case(void)
 		struct s_fx *data = (void *)col->entry;
 		int i;
 
-		/* TODO: Check header */
+		/* TODO: Check entity header */
 		p += NON_IMAGETTE_HEADER_SIZE;
 
 		TEST_ASSERT_EQUAL_HEX8_ARRAY(&cmp_collection_size_exp, p, CMP_COLLECTION_FILD_SIZE);
@@ -1383,18 +1531,17 @@ void test_cmp_decmp_chunk_worst_case(void)
 	{
 		void *decompressed_data = NULL;
 		int decmp_size = decompress_cmp_entiy((void *)dst, NULL, NULL, decompressed_data);
+
 		TEST_ASSERT_EQUAL_size_t(chunk_size, decmp_size);
 		decompressed_data = malloc((size_t)decmp_size); TEST_ASSERT_NOT_NULL(decompressed_data);
 		decmp_size = decompress_cmp_entiy((void *)dst, NULL, NULL, decompressed_data);
 
 		TEST_ASSERT_EQUAL_INT(chunk_size, decmp_size);
 		TEST_ASSERT_EQUAL_HEX8_ARRAY(chunk, decompressed_data, chunk_size);
+		free(decompressed_data);
 	}
 
-	/* error cases */
-	memset(dst, 0, sizeof(dst));
-
-	/* buffer to small for compressed data */
+	/* error case: buffer to small for compressed data */
 	cmp_size_byte = compress_chunk(chunk, chunk_size, NULL, NULL, dst, chunk_size, &par);
 	TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, cmp_size_byte);
 
@@ -1405,13 +1552,11 @@ void test_cmp_decmp_chunk_worst_case(void)
 void test_cmp_decmp_diff(void)
 {
 	struct chunk_def chunk_def[2] = {{DATA_TYPE_S_FX, 2}, {DATA_TYPE_S_FX_EFX_NCOB_ECOB, 3}};
-	size_t chunk_size;
+	uint32_t chunk_size;
 	void *chunk = NULL;
 	uint32_t *dst = NULL;
-	int dst_capacity = 0;
 
-	/* generate test data */
-	{
+	{ /* generate test data */
 		struct s_fx *col_data1;
 		struct s_fx_efx_ncob_ecob *col_data2;
 		struct collection_hdr *col;
@@ -1456,10 +1601,10 @@ void test_cmp_decmp_diff(void)
 		col_data2[2].ecob_y = 2;
 	}
 
-
-	/* compress data */
-	{
+	{ /* compress data */
 		struct cmp_par par = {0};
+		uint32_t dst_capacity = 0;
+		int cmp_size;
 
 		par.cmp_mode = CMP_MODE_DIFF_ZERO;
 		par.s_exp_flags = 1;
@@ -1469,13 +1614,13 @@ void test_cmp_decmp_diff(void)
 		par.s_ecob = 5;
 
 
-		dst_capacity = compress_chunk(chunk, chunk_size, NULL, NULL, dst, dst_capacity, &par);
-		TEST_ASSERT_GREATER_THAN_INT(0, dst_capacity);
-		/* TODO: */ dst_capacity = ROUND_UP_TO_MULTIPLE_OF_4(dst_capacity);
+		cmp_size = compress_chunk(chunk, chunk_size, NULL, NULL, dst, dst_capacity, &par);
+		TEST_ASSERT_GREATER_THAN_INT(0, cmp_size);
+		dst_capacity = (uint32_t)ROUND_UP_TO_MULTIPLE_OF_4(cmp_size);
 		dst = malloc(dst_capacity);
 		TEST_ASSERT_NOT_NULL(dst);
-		dst_capacity = compress_chunk(chunk, chunk_size, NULL, NULL, dst, dst_capacity, &par);
-		TEST_ASSERT_GREATER_THAN_INT(0, dst_capacity);
+		cmp_size = compress_chunk(chunk, chunk_size, NULL, NULL, dst, dst_capacity, &par);
+		TEST_ASSERT_GREATER_THAN_INT(0, cmp_size);
 	}
 	{
 		void *decompressed_data = NULL;
@@ -1488,5 +1633,7 @@ void test_cmp_decmp_diff(void)
 
 		TEST_ASSERT_EQUAL_INT(chunk_size, decmp_size);
 		TEST_ASSERT_EQUAL_HEX8_ARRAY(chunk, decompressed_data, chunk_size);
+		free(decompressed_data);
 	}
+	free(dst);
 }
-- 
GitLab