diff --git a/lib/cmp_icu_new.c b/lib/cmp_icu_new.c
index e6f6752e6297f68c8cae3971066191cb8ae3ca9b..f4bec3665d54726e3910055fc0f20a0f02053aca 100644
--- a/lib/cmp_icu_new.c
+++ b/lib/cmp_icu_new.c
@@ -26,6 +26,52 @@
 /* return code if the bitstream buffer is too small to store the whole bitstream */
 #define CMP_ERROR_SAMLL_BUF -2
 
+/* pointer to a code word generation function */
+typedef uint32_t (*generate_cw_pt)(uint32_t value, uint32_t encoder_par1,
+				   uint32_t encoder_par2, uint32_t *cw);
+
+/* typedef uint32_t (*next_model_f_pt)(uint32_t model_mode_val, uint32_t diff_model_var); */
+
+struct encoder_setupt {
+	/* unsigned int lossy_par; */
+	/* next_model_f_pt *next_model_f; */
+	generate_cw_pt generate_cw; /* pointer to the code word generation function */
+	/* uint32_t updated_model; */
+	uint32_t encoder_par1;
+	uint32_t encoder_par2;
+	uint32_t outlier_par;
+	uint32_t model_value;
+	uint32_t max_value_bits; /* how many bits are needed to represent the highest possible value */
+	uint32_t max_bit_len; /* maximum length of the bitstream/icu_output_buf in bits */
+	uint32_t *bitstream_adr;
+};
+
+
+/**
+ * @brief map a signed value into a positive value range
+ *
+ * @param value_to_map		signed value to map
+ * @param max_value_bits	how many bits are needed to represent the
+ *				highest possible value
+ *
+ * @returns the positive mapped value
+ */
+
+static uint32_t map_to_pos(uint32_t value_to_map, unsigned int max_value_bits)
+{
+	uint32_t mask = (~0U >> (32 - max_value_bits)); /* mask the used bits */
+
+	value_to_map &= mask;
+	if (value_to_map >> (max_value_bits - 1)) { /* check the leading signed bit */
+		value_to_map |= ~mask; /* convert to 32-bit signed integer */
+		/* map negative values to uneven numbers */
+		return (-value_to_map) * 2 - 1; /* possible integer overflow is intended */
+	} else {
+		/* map positive values to even numbers */
+		return value_to_map * 2; /* possible integer overflow is intended */
+	}
+}
+
 
 /**
  * @brief put the value of up to 32 bits into a bitstream accessed as 32-bit
@@ -43,8 +89,6 @@
  * @returns length in bits of the generated bitstream on success; returns
  *          negative in case of erroneous input; returns CMP_ERROR_SAMLL_BUF if
  *          the bitstream buffer is too small to put the value in the bitstream
- * @note a value with more bits set as the n_bits parameter is considered as an
- *	erroneous input.
  */
 
 static int put_n_bits32(uint32_t value, unsigned int n_bits, int bit_offset,
@@ -60,21 +104,11 @@ static int put_n_bits32(uint32_t value, unsigned int n_bits, int bit_offset,
 		return -1;
 
 	if (n_bits == 0)
-		return 0;
+		return stream_len;
 
 	if (n_bits > 32)
 		return -1;
 
-	/* (M) is the n_bits parameter large enough to cover all value bits; the
-	 * calculations can be re-used in the unsegmented code, so we have no overhead
-	 */
-	shiftRight = 32 - n_bits;
-	mask = 0xFFFFFFFFU >> shiftRight;
-	if (value & ~mask) {
-		debug_print("Error: Not all set bits in the put value are added to the bitstream. Check value n_bits parameter combination.\n");
-		return -1;
-	}
-
 	/* Do we need to write data to the bitstream? */
 	if (!bitstream_adr)
 		return stream_len;
@@ -85,6 +119,13 @@ static int put_n_bits32(uint32_t value, unsigned int n_bits, int bit_offset,
 		return CMP_ERROR_SAMLL_BUF;
 	}
 
+	/* (M) is the n_bits parameter large enough to cover all value bits; the
+	 * calculations can be re-used in the unsegmented code, so we have no overhead
+	 */
+	shiftRight = 32 - n_bits;
+	mask = 0xFFFFFFFFU >> shiftRight;
+	value &= mask;
+
 	/* Separate the bit_offset into word offset (set local_adr pointer) and local bit offset (bitsLeft) */
 	local_adr = bitstream_adr + (bit_offset >> 5);
 	bitsLeft = bit_offset & 0x1F;
@@ -163,3 +204,235 @@ static int put_n_bits32(uint32_t value, unsigned int n_bits, int bit_offset,
 	return stream_len;
 }
 
+
+/**
+ * @brief forms the codeword according to the Rice code
+ *
+ * @param value		value to be encoded
+ * @param m		Golomb parameter, only m's which are power of 2 are allowed
+ * @param log2_m	Rice parameter, is log_2(m) calculate outside function
+ *			for better performance
+ * @param cw		address were the encode code word is stored
+ *
+ * @returns the length of the formed code word in bits
+ * @note no check if the generated code word is not longer than 32 bits.
+ */
+
+static uint32_t Rice_encoder(uint32_t value, uint32_t m, uint32_t log2_m,
+				 uint32_t *cw)
+{
+	uint32_t g;  /* quotient of value/m */
+	uint32_t q;  /* quotient code without ending zero */
+	uint32_t r;  /* remainder of value/m */
+	uint32_t rl; /* remainder length */
+
+	g = value >> log2_m; /* quotient, number of leading bits */
+	q = (1U << g) - 1;   /* prepare the quotient code without ending zero */
+
+	r = value & (m-1);   /* calculate the remainder */
+	rl = log2_m + 1;     /* length of the remainder (+1 for the 0 in the quotient code) */
+	*cw = (q << rl) | r; /* put the quotient and remainder code together */
+	/*
+	 * NOTE: If log2_m = 31 -> rl = 32, (q << rl) leads to an undefined
+	 * behavior. However, in this case, a valid code with a maximum of 32
+	 * bits can only be formed if q = 0. Any shift with 0 << x always
+	 * results in 0, which forms the correct codeword in this case. For
+	 * performance reasons, this undefined behaviour is not caught.
+	 */
+
+	return rl + g;	      /* calculate the length of the code word */
+}
+
+
+/**
+ * @brief forms a codeword according to the Golomb code
+ *
+ * @param value		value to be encoded
+ * @param m		Golomb parameter (have to be bigger than 0)
+ * @param log2_m	is log_2(m) calculate outside function for better
+ *			performance
+ * @param cw		address were the formed code word is stored
+ *
+ * @returns the length of the formed code word in bits
+ */
+
+static uint32_t Golomb_encoder(uint32_t value, uint32_t m, uint32_t log2_m,
+				   uint32_t *cw)
+{
+	uint32_t len0, b, g, q, lg;
+	uint32_t len;
+	uint32_t cutoff;
+
+	len0 = log2_m + 1;                 /* codeword length in group 0 */
+	cutoff = (1U << (log2_m + 1)) - m; /* members in group 0 */
+
+	if (value < cutoff) { /* group 0 */
+		*cw = value;
+		len = len0;
+	} else { /* other groups */
+		g = (value-cutoff) / m; /* this group is which one  */
+		b = cutoff << 1;        /* form the base codeword */
+		lg = len0 + g;          /* it has lg remainder bits */
+		q = (1U << g) - 1;      /* prepare the left side in unary */
+		*cw = (q << (len0+1)) + b + (value-cutoff) - g*m; /* composed codeword */
+		len = lg + 1;           /* length of the codeword */
+	}
+	return len;
+}
+
+
+/**
+ * @brief generate a code word without a outlier mechanism and put in the
+ *	bitstream
+ *
+ * @param value		value to encode in the bitstream
+ * @param stream_len	length of the bitstream in bits
+ * @param setup		pointer to the encoder setup
+ *
+ * @returns the bit length of the bitstream with the added encoded value on
+ *	success; negative on error
+ */
+
+static int encode_normal(uint32_t value, int stream_len,
+			 struct encoder_setupt *setup)
+{
+	uint32_t code_word, cw_len;
+
+	cw_len = setup->generate_cw(value, setup->encoder_par1,
+				    setup->encoder_par2, &code_word);
+
+	return put_n_bits32(code_word, cw_len, stream_len, setup->bitstream_adr,
+			    setup->max_bit_len);
+}
+
+
+/**
+ * @brief subtract the model from the data and encode the result and put it into
+ *	bitstream, for outlier use the zero escape symbol mechanism
+ *
+ * @param data		data to encode
+ * @param model		model of the data (0 if not used)
+ * @param stream_len	length of the bitstream in bits
+ * @param setup		pointer to the encoder setup
+ *
+ * @returns the bit length of the bitstream with the added encoded value on
+ *	success; negative on error
+ *
+ * @note no check if data or model are in the allowed range
+ */
+
+static int encode_value_zero(uint32_t data, uint32_t model, int stream_len,
+			     struct encoder_setupt *setup)
+{
+	data -= model;
+
+	data = map_to_pos(data, setup->max_value_bits);
+
+	/* For performance reasons we check if there is an outlier before adding
+	 * one to the data, than the other way around:
+	 * data++;
+	 * if (data < setup->outlier_par && data != 0)
+	 *	return ...
+	 */
+	if (data < (setup->outlier_par - 1)) {
+		data++; /* add 1 to every value so we can use 0 as escape symbol */
+		return encode_normal(data, stream_len, setup);
+	}
+
+	data++; /* add 1 to every value so we can use 0 as escape symbol */
+
+	/* use zero as escape symbol */
+	stream_len = encode_normal(0, stream_len, setup);
+	if (stream_len <= 0)
+		return stream_len;
+
+	/* put the data unencoded in the bitstream */
+	stream_len = put_n_bits32(data, setup->max_value_bits, stream_len,
+				  setup->bitstream_adr, setup->max_bit_len);
+
+	return stream_len;
+
+}
+
+
+static int cal_multi_offset(unsigned int unencoded_data)
+{
+	if (unencoded_data <= 0x3)
+		return 0;
+	if (unencoded_data <= 0xF)
+		return 1;
+	if (unencoded_data <= 0x3F)
+		return 2;
+	if (unencoded_data <= 0xFF)
+		return 3;
+	if (unencoded_data <= 0x3FF)
+		return 4;
+	if (unencoded_data <= 0xFFF)
+		return 5;
+	if (unencoded_data <= 0x3FFF)
+		return 6;
+	if (unencoded_data <= 0xFFFF)
+		return 7;
+	if (unencoded_data <= 0x3FFFF)
+		return 8;
+	if (unencoded_data <= 0xFFFFF)
+		return 9;
+	if (unencoded_data <= 0x3FFFFF)
+		return 10;
+	if (unencoded_data <= 0xFFFFFF)
+		return 11;
+	if (unencoded_data <= 0x3FFFFFF)
+		return 12;
+	if (unencoded_data <= 0xFFFFFFF)
+		return 13;
+	if (unencoded_data <= 0x3FFFFFFF)
+		return 14;
+	else
+		return 15;
+}
+
+
+#if 0
+static int encode_value_multi(uint32_t data, uint32_t model, int stream_len,
+			      struct encoder_setupt *setup)
+{
+	uint32_t unencoded_data;
+	unsigned int unencoded_data_len;
+	uint32_t escape_sym;
+	uint32_t escape_sym_offset;
+
+	data -= model; /* possible underflow is intended */
+
+	data = map_to_pos(data, setup->max_value_bits);
+
+	if (data < setup->outlier_par)
+		return  encode_normal(data, stream_len, setup);
+	/*
+	 * In this mode we put the difference between the data and the spillover
+	 * threshold value (unencoded_data) after a encoded escape symbol, which
+	 * indicate that the next codeword is unencoded.
+	 * We use different escape symbol depended on the size the needed bit of
+	 * unencoded data:
+	 * 0, 1, 2 bits needed for unencoded data -> escape symbol is spill + 0
+	 * 3, 4 bits needed for unencoded data -> escape symbol is spill + 1
+	 * ..
+	 */
+
+	unencoded_data = data - setup->outlier_par;
+
+	escape_sym_offset = cal_multi_offset(unencoded_data);
+	escape_sym  = setup->outlier_par + escape_sym_offset;
+	unencoded_data_len = (escape_sym_offset + 1) * 2;
+
+	/* put the escape symbol in the bitstream */
+	stream_len = encode_normal(escape_sym, stream_len, setup);
+	if (stream_len <= 0)
+		return stream_len;
+
+	/* put the unencoded data in the bitstream */
+	stream_len = put_n_bits32(unencoded_data, unencoded_data_len, stream_len,
+				  setup->bitstream_adr, setup->max_bit_len);
+
+	return stream_len;
+}
+#endif
diff --git a/test/cmp_icu/test_cmp_icu_new.c b/test/cmp_icu/test_cmp_icu_new.c
index 6e5761528a50305999b110a74120a05f70508e01..986b7b648a0f73c5ab800860afa720fc72f37502 100644
--- a/test/cmp_icu/test_cmp_icu_new.c
+++ b/test/cmp_icu/test_cmp_icu_new.c
@@ -2,10 +2,99 @@
 
 #include "unity.h"
 
+#include "cmp_support.h"
 /* this is a hack to test static functions */
 #include "../lib/cmp_icu_new.c"
 
 
+/**
+* @test map_to_pos
+*/
+
+void test_map_to_pos(void)
+{
+	uint32_t value_to_map;
+	uint32_t max_value_bits;
+	uint32_t mapped_value;
+
+	/* test mapping 32 bits values */
+	max_value_bits = 32;
+
+	value_to_map = 0;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(0, mapped_value);
+
+	value_to_map = -1U;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(1, mapped_value);
+
+	value_to_map = 1;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(2, mapped_value);
+
+	value_to_map = 42;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(84, mapped_value);
+
+	value_to_map = INT32_MAX;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_HEX(UINT32_MAX-1, mapped_value);
+
+	value_to_map = INT32_MIN;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_HEX(UINT32_MAX, mapped_value);
+
+	/* test mapping 16 bits values */
+	max_value_bits = 16;
+
+	value_to_map = -1U;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(1, mapped_value);
+
+	/* test mapping 6 bits values */
+	max_value_bits = 6;
+
+	value_to_map = 0;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(0, mapped_value);
+
+	value_to_map = -1U;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(1, mapped_value);
+
+	value_to_map = UINT32_MAX;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(1, mapped_value);
+
+	value_to_map = -1U & 0x3FU;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(1, mapped_value);
+
+	value_to_map = 63;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(1, mapped_value);
+
+	value_to_map = 1;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(2, mapped_value);
+
+	value_to_map = 31;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(62, mapped_value);
+
+	value_to_map = -33U; /* aka 31 */
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(62, mapped_value);
+
+	value_to_map = -32U;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(63, mapped_value);
+
+	value_to_map = 32;
+	mapped_value = map_to_pos(value_to_map, max_value_bits);
+	TEST_ASSERT_EQUAL_INT(63, mapped_value);
+}
+
 
 /**
  * @test put_n_bits32
@@ -42,7 +131,11 @@ void test_put_n_bits32(void)
 
 	init_PB32_arrays(testarray0, testarray1);
 	TEST_ASSERT(testarray0[0] == 0);
+	TEST_ASSERT(testarray0[1] == 0);
+	TEST_ASSERT(testarray0[2] == 0);
 	TEST_ASSERT(testarray1[0] == 0xffffffff);
+	TEST_ASSERT(testarray1[1] == 0xffffffff);
+	TEST_ASSERT(testarray1[2] == 0xffffffff);
 
 	/*** n=0 ***/
 
@@ -56,7 +149,9 @@ void test_put_n_bits32(void)
 	TEST_ASSERT_EQUAL_INT(0, rval);
 	TEST_ASSERT(testarray1[0] == 0xffffffff);
 
-	/* TODO: not a valid test */
+	rval = put_n_bits32(v, n, o, NULL, l);
+	TEST_ASSERT_EQUAL_INT(0, rval);
+
 	v = 0xffffffff; n = 0; o = 0;
 	rval = put_n_bits32(v, n, o, testarray0, l);
 	TEST_ASSERT_EQUAL_INT(0, rval);
@@ -66,27 +161,35 @@ void test_put_n_bits32(void)
 	TEST_ASSERT_EQUAL_INT(0, rval);
 	TEST_ASSERT(testarray1[0] == 0xffffffff);
 
+	rval = put_n_bits32(v, n, o, NULL, l);
+	TEST_ASSERT_EQUAL_INT(0, rval);
+
 	/* do not write, right border */
-	v = 0; n = 0; o = 31;
+	v = 0; n = 0; o = l;
 	rval = put_n_bits32(v, n, o, testarray0, l);
-	TEST_ASSERT_EQUAL_INT(0, rval);
+	TEST_ASSERT_EQUAL_INT(l, rval);
 	TEST_ASSERT(testarray0[0] == 0);
 
 	rval = put_n_bits32(v, n, o, testarray1, l);
-	TEST_ASSERT_EQUAL_INT(0, rval);
+	TEST_ASSERT_EQUAL_INT(l, rval);
 	TEST_ASSERT(testarray1[0] == 0xffffffff);
 
-	/* TODO: not a valid test */
+	rval = put_n_bits32(v, n, o, NULL, l);
+	TEST_ASSERT_EQUAL_INT(l, rval);
+
 	/* test value = 0xffffffff; N = 0 */
-	v = 0xffffffff; n = 0; o = 31;
+	v = 0xffffffff; n = 0; o = l;
 	rval = put_n_bits32(v, n, o, testarray0, l);
-	TEST_ASSERT_EQUAL_INT(0, rval);
+	TEST_ASSERT_EQUAL_INT(l, rval);
 	TEST_ASSERT(testarray0[0] == 0);
 
 	rval = put_n_bits32(v, n, o, testarray1, l);
-	TEST_ASSERT_EQUAL_INT(0, rval);
+	TEST_ASSERT_EQUAL_INT(l, rval);
 	TEST_ASSERT(testarray1[0] == 0xffffffff);
 
+	rval = put_n_bits32(v, n, o, NULL, l);
+	TEST_ASSERT_EQUAL_INT(l, rval);
+
 	/*** n=1 ***/
 
 	/* left border, write 0 */
@@ -114,10 +217,12 @@ void test_put_n_bits32(void)
 	rval = put_n_bits32(v, n, o, testarray0, l);
 	TEST_ASSERT_EQUAL_INT(rval, 32);
 	TEST_ASSERT(testarray0[0] == 0xf0f0abcd);
+	TEST_ASSERT(testarray0[1] == 0);
 
 	rval = put_n_bits32(v, n, o, testarray1, l);
 	TEST_ASSERT_EQUAL_INT(rval, 32);
 	TEST_ASSERT(testarray1[0] == 0xf0f0abcd);
+	TEST_ASSERT(testarray1[1] == 0xffffffff);
 	/* re-init input arrays after clobbering */
 	init_PB32_arrays(testarray0, testarray1);
 
@@ -317,26 +422,49 @@ void test_put_n_bits32(void)
 	rval = put_n_bits32(v, n, o, NULL, l);
 	TEST_ASSERT_EQUAL_INT(rval, 97); /* rval can be longer than l */
 
-	/* error cases */
-	/* n too large */
-	v = 0x0; n = 33; o = 1;
+	/* value larger than n allows */
+	v = 0x7f; n = 6; o = 10;
 	rval = put_n_bits32(v, n, o, testarray0, l);
-	TEST_ASSERT_EQUAL_INT(rval, -1);
-	TEST_ASSERT(testarray0[0] == 0);
+	TEST_ASSERT_EQUAL_INT(16, rval);
+	TEST_ASSERT(testarray0[0] == 0x003f0000);
+	TEST_ASSERT(testarray0[1] == 0);
+
+	rval = put_n_bits32(v, n, o, testarray1, l);
+	TEST_ASSERT_EQUAL_INT(16, rval);
+	TEST_ASSERT(testarray1[0] == 0xffffffff);
+	TEST_ASSERT(testarray1[1] == 0xffffffff);
+
+	rval = put_n_bits32(v, n, o, NULL, l);
+	TEST_ASSERT_EQUAL_INT(16, rval);
+	/* re-init input arrays after clobbering */
+	init_PB32_arrays(testarray0, testarray1);
+
+	v = 0xffffffff; n = 6; o = 10;
+	rval = put_n_bits32(v, n, o, testarray0, l);
+	TEST_ASSERT_EQUAL_INT(16, rval);
+	TEST_ASSERT(testarray0[0] == 0x003f0000);
 	TEST_ASSERT(testarray0[1] == 0);
 
+	rval = put_n_bits32(v, n, o, testarray1, l);
+	TEST_ASSERT_EQUAL_INT(16, rval);
+	TEST_ASSERT(testarray1[0] == 0xffffffff);
+	TEST_ASSERT(testarray1[1] == 0xffffffff);
+
 	rval = put_n_bits32(v, n, o, NULL, l);
-	TEST_ASSERT_EQUAL_INT(rval, -1);
+	TEST_ASSERT_EQUAL_INT(16, rval);
+	/* re-init input arrays after clobbering */
+	init_PB32_arrays(testarray0, testarray1);
 
-	/* value larger than n allows */
-	v = 0x7f; n = 6; o = 10;
+	/*** error cases ***/
+	/* n too large */
+	v = 0x0; n = 33; o = 1;
 	rval = put_n_bits32(v, n, o, testarray0, l);
-	TEST_ASSERT_EQUAL_INT(-1, rval);
+	TEST_ASSERT_EQUAL_INT(rval, -1);
 	TEST_ASSERT(testarray0[0] == 0);
 	TEST_ASSERT(testarray0[1] == 0);
 
 	rval = put_n_bits32(v, n, o, NULL, l);
-	TEST_ASSERT_EQUAL_INT(-1, rval);
+	TEST_ASSERT_EQUAL_INT(rval, -1);
 
 	/* try to put too much in the bitstream */
 	v = 0x1; n = 1; o = 96;
@@ -346,11 +474,11 @@ void test_put_n_bits32(void)
 	TEST_ASSERT(testarray0[1] == 0);
 	TEST_ASSERT(testarray0[2] == 0);
 
-	/* this should work */
+	/* this should work (if bitstream=NULL no length check) */
 	rval = put_n_bits32(v, n, o, NULL, l);
 	TEST_ASSERT_EQUAL_INT(97, rval);
 
-	/* offset lager than max_bit_len */
+	/* offset lager than max_bit_len(l) */
 	v = 0x0; n = 32; o = INT32_MAX;
 	rval = put_n_bits32(v, n, o, testarray1, l);
 	TEST_ASSERT_EQUAL_INT(CMP_ERROR_SAMLL_BUF, rval);
@@ -370,4 +498,305 @@ void test_put_n_bits32(void)
 
 	rval = put_n_bits32(v, n, o, NULL, l);
 	TEST_ASSERT_EQUAL_INT(-1, rval);
+
+	v = 0x0; n = 0; o = -2;
+	rval = put_n_bits32(v, n, o, testarray0, l);
+	TEST_ASSERT_EQUAL_INT(-1, rval);
+	TEST_ASSERT(testarray0[0] == 0);
+	TEST_ASSERT(testarray0[1] == 0);
+
+	rval = put_n_bits32(v, n, o, NULL, l);
+	TEST_ASSERT_EQUAL_INT(-1, rval);
+}
+
+
+/**
+ * @test Rice_encoder
+ */
+
+void test_Rice_encoder(void)
+{
+	uint32_t value, g_par, log2_g_par, cw, cw_len;
+
+	/* 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;
+	cw_len = Rice_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(1, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x0, cw);
+
+	value = 31;
+	cw_len = Rice_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFE, cw);
+
+	/* test some arbitrary values */
+	value = 0; log2_g_par = 4; g_par = 1U << log2_g_par; cw = ~0U;
+	cw_len = Rice_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(5, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x0, cw);
+
+	value = 1;
+	cw_len = Rice_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(5, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x1, cw);
+
+	value = 42;
+	cw_len = Rice_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(7, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x6a, cw);
+
+	value = 446;
+	cw_len = Rice_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFEE, cw);
+
+	value = 447;
+	cw_len = Rice_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	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;
+	cw_len = Rice_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x0, cw);
+
+	value = 1;
+	cw_len = Rice_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x1, cw);
+
+	value = 0x7FFFFFFE;
+	cw_len = Rice_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x7FFFFFFE, cw);
+
+	value = 0x7FFFFFFF;
+	cw_len = Rice_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x7FFFFFFF, cw);
+}
+
+
+/**
+ * @test Golomb_encoder
+ */
+
+void test_Golomb_encoder(void)
+{
+	uint32_t value, g_par, log2_g_par, cw, cw_len;
+
+	/* test minimum Golomb parameter */
+	value = 0; g_par = MIN_ICU_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(1, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x0, cw);
+
+	value = 31;
+	cw_len = Golomb_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFE, cw);
+
+
+	/* test some arbitrary values with g_par = 16 */
+	value = 0; g_par = 16; 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(5, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x0, cw);
+
+	value = 1;
+	cw_len = Golomb_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(5, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x1, cw);
+
+	value = 42;
+	cw_len = Golomb_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(7, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x6a, cw);
+
+	value = 446;
+	cw_len = Golomb_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFEE, cw);
+
+	value = 447;
+	cw_len = Golomb_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFEF, cw);
+
+
+	/* test some arbitrary values with g_par = 3 */
+	value = 0; g_par = 3; 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(2, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x0, cw);
+
+	value = 1;
+	cw_len = Golomb_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(3, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x2, cw);
+
+	value = 42;
+	cw_len = Golomb_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(16, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0xFFFC, cw);
+
+	value = 44;
+	cw_len = Golomb_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(17, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x1FFFB, cw);
+
+	value = 88;
+	cw_len = Golomb_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFA, cw);
+
+	value = 89;
+	cw_len = Golomb_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFB, cw);
+
+
+	/* 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;
+	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;
+	cw_len = Golomb_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x1, cw);
+
+	value = 0x7FFFFFFE;
+	cw_len = Golomb_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x7FFFFFFE, cw);
+
+	value = 0x7FFFFFFF;
+	cw_len = Golomb_encoder(value, g_par, log2_g_par, &cw);
+	TEST_ASSERT_EQUAL_INT(32, cw_len);
+	TEST_ASSERT_EQUAL_HEX(0x7FFFFFFF, cw);
+}
+
+
+/**
+ * @test encode_value_zero
+ */
+
+void test_encode_value_zero(void)
+{
+	uint32_t data, model;
+	int stream_len;
+	struct encoder_setupt setup = {0};
+	uint32_t bitstream[3] = {0};
+
+	/* setup the setup */
+	setup.encoder_par1 = 1;
+	setup.encoder_par2 = (uint32_t)ilog_2(setup.encoder_par1);
+	setup.outlier_par = 32;
+	setup.max_value_bits = 32;
+	setup.generate_cw = Rice_encoder;
+	setup.bitstream_adr = bitstream;
+	setup.max_bit_len = sizeof(bitstream) * CHAR_BIT;
+
+	stream_len = 0;
+
+	data = 0; model = 0;
+	stream_len = encode_value_zero(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(2, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0x80000000, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
+
+	data = 5; model = 0;
+	stream_len = encode_value_zero(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(14, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0xBFF80000, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
+
+	data = 2; model = 7;
+	stream_len = encode_value_zero(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(25, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0xBFFBFF00, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
+
+	/* zero escape mechanism */
+	data = 100; model = 42;
+	/* (100-42)*2+1=117 -> cw 0 + 0x0000_0000_0000_0075 */
+	stream_len = encode_value_zero(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(58, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0xBFFBFF00, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0x00001D40, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
+
+	/* test overflow */
+	data = INT32_MIN; model = 0;
+	/* (INT32_MIN)*-2-1+1=0(overflow) -> cw 0 + 0x0000_0000_0000_0000 */
+	stream_len = encode_value_zero(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(91, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0xBFFBFF00, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0x00001D40, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
+
+	/* small buffer error */
+	data = 23; model = 26;
+	stream_len = encode_value_zero(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(CMP_ERROR_SAMLL_BUF, stream_len);
+
+	/* reset bitstream to all bits set */
+	bitstream[0] = ~0U;
+	bitstream[1] = ~0U;
+	bitstream[2] = ~0U;
+	stream_len = 0;
+
+	/* we use now values with maximum 6 bits */
+	setup.max_value_bits = 6;
+
+	/* lowest value before zero encoding */
+	data = 53; model = 38;
+	stream_len = encode_value_zero(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(32, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFE, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFF, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFF, bitstream[2]);
+
+	/* lowest value with zero encoding */
+	data = 0; model = 16;
+	stream_len = encode_value_zero(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(39, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFE, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0x41FFFFFF, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFF, bitstream[2]);
+
+	/* maximum positive value to encode */
+	data = 31; model = 0;
+	stream_len = encode_value_zero(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(46, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFE, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0x40FFFFFF, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFF, bitstream[2]);
+
+	/* maximum negative value to encode */
+	data = -32U; model = 0;
+	stream_len = encode_value_zero(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(53, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFE, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0x40FC07FF, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFF, bitstream[2]);
+
+	/* small buffer error when creating the zero escape symbol*/
+	bitstream[0] = 0;
+	bitstream[1] = 0;
+	bitstream[2] = 0;
+	stream_len = 32;
+	setup.max_bit_len = 32;
+	data = 31; model = 0;
+	stream_len = encode_value_zero(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(-2, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0, bitstream[2]);
 }