Skip to content
Snippets Groups Projects
Commit 83ba84a1 authored by Dominik Loidolt's avatar Dominik Loidolt
Browse files

refactor and test encode_value_multi()

parent b402a986
No related branches found
No related tags found
1 merge request!11decompression/compression for non-imagette data
...@@ -307,8 +307,8 @@ static int encode_normal(uint32_t value, int stream_len, ...@@ -307,8 +307,8 @@ static int encode_normal(uint32_t value, int stream_len,
/** /**
* @brief subtract the model from the data and encode the result and put it into * @brief subtract the model from the data, encode the result and put it into
* bitstream, for outlier use the zero escape symbol mechanism * bitstream, for encodeing outlier use the zero escape symbol mechanism
* *
* @param data data to encode * @param data data to encode
* @param model model of the data (0 if not used) * @param model model of the data (0 if not used)
...@@ -316,9 +316,11 @@ static int encode_normal(uint32_t value, int stream_len, ...@@ -316,9 +316,11 @@ static int encode_normal(uint32_t value, int stream_len,
* @param setup pointer to the encoder setup * @param setup pointer to the encoder setup
* *
* @returns the bit length of the bitstream with the added encoded value on * @returns the bit length of the bitstream with the added encoded value on
* success; negative on error * success; negative on error, CMP_ERROR_SAMLL_BUF if the bitstream buffer
* is too small to put the value in the bitstream
* *
* @note no check if data or model are in the allowed range * @note no check if data or model are in the allowed range
* @note no check if the setup->outlier_par is in the allowed range
*/ */
static int encode_value_zero(uint32_t data, uint32_t model, int stream_len, static int encode_value_zero(uint32_t data, uint32_t model, int stream_len,
...@@ -328,13 +330,13 @@ static int encode_value_zero(uint32_t data, uint32_t model, int stream_len, ...@@ -328,13 +330,13 @@ static int encode_value_zero(uint32_t data, uint32_t model, int stream_len,
data = map_to_pos(data, setup->max_value_bits); data = map_to_pos(data, setup->max_value_bits);
/* For performance reasons we check if there is an outlier before adding /* For performance reasons, we check to see if there is an outlier
* one to the data, than the other way around: * before adding one, rather than the other way around:
* data++; * data++;
* if (data < setup->outlier_par && data != 0) * if (data < setup->outlier_par && data != 0)
* return ... * return ...
*/ */
if (data < (setup->outlier_par - 1)) { if (data < (setup->outlier_par - 1)) { /* detect r */
data++; /* add 1 to every value so we can use 0 as escape symbol */ data++; /* add 1 to every value so we can use 0 as escape symbol */
return encode_normal(data, stream_len, setup); return encode_normal(data, stream_len, setup);
} }
...@@ -355,74 +357,57 @@ static int encode_value_zero(uint32_t data, uint32_t model, int stream_len, ...@@ -355,74 +357,57 @@ static int encode_value_zero(uint32_t data, uint32_t model, int stream_len,
} }
static int cal_multi_offset(unsigned int unencoded_data) /**
{ * @brief subtract the model from the data, encode the result and put it into
if (unencoded_data <= 0x3) * bitstream, for encoding outlier use the multi escape symbol mechanism
return 0; *
if (unencoded_data <= 0xF) * @param data data to encode
return 1; * @param model model of the data (0 if not used)
if (unencoded_data <= 0x3F) * @param stream_len length of the bitstream in bits
return 2; * @param setup pointer to the encoder setup
if (unencoded_data <= 0xFF) *
return 3; * @returns the bit length of the bitstream with the added encoded value on
if (unencoded_data <= 0x3FF) * success; negative on error, CMP_ERROR_SAMLL_BUF if the bitstream buffer
return 4; * is too small to put the value in the bitstream
if (unencoded_data <= 0xFFF) *
return 5; * @note no check if data or model are in the allowed range
if (unencoded_data <= 0x3FFF) * @note no check if the setup->outlier_par is in the allowed ragne
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, static int encode_value_multi(uint32_t data, uint32_t model, int stream_len,
struct encoder_setupt *setup) struct encoder_setupt *setup)
{ {
uint32_t unencoded_data; uint32_t unencoded_data;
unsigned int unencoded_data_len; unsigned int unencoded_data_len;
uint32_t escape_sym; uint32_t escape_sym, escape_sym_offset;
uint32_t escape_sym_offset;
data -= model; /* possible underflow is intended */ data -= model; /* possible underflow is intended */
data = map_to_pos(data, setup->max_value_bits); data = map_to_pos(data, setup->max_value_bits);
if (data < setup->outlier_par) if (data < setup->outlier_par) /* detect non-outlier */
return encode_normal(data, stream_len, setup); return encode_normal(data, stream_len, setup);
/* /*
* In this mode we put the difference between the data and the spillover * In this mode we put the difference between the data and the spillover
* threshold value (unencoded_data) after a encoded escape symbol, which * threshold value (unencoded_data) after a encoded escape symbol, which
* indicate that the next codeword is unencoded. * indicate that the next codeword is unencoded.
* We use different escape symbol depended on the size the needed bit of * We use different escape symbol depended on the size the needed bit of
* unencoded data: * unencoded data:
* 0, 1, 2 bits needed for unencoded data -> escape symbol is spill + 0 * 0, 1, 2 bits needed for unencoded data -> escape symbol is outlier_par + 0
* 3, 4 bits needed for unencoded data -> escape symbol is spill + 1 * 3, 4 bits needed for unencoded data -> escape symbol is outlier_par + 1
* .. * 5, 6 bits needed for unencoded data -> escape symbol is outlier_par + 2
* and so on
*/ */
unencoded_data = data - setup->outlier_par; unencoded_data = data - setup->outlier_par;
escape_sym_offset = cal_multi_offset(unencoded_data); if (!unencoded_data) /* catch __builtin_clz(0) because the result is undefined.*/
escape_sym_offset = 0;
else
escape_sym_offset = (31U - (uint32_t)__builtin_clz(unencoded_data)) >> 1;
escape_sym = setup->outlier_par + escape_sym_offset; escape_sym = setup->outlier_par + escape_sym_offset;
unencoded_data_len = (escape_sym_offset + 1) * 2; unencoded_data_len = (escape_sym_offset + 1U) << 1;
/* put the escape symbol in the bitstream */ /* put the escape symbol in the bitstream */
stream_len = encode_normal(escape_sym, stream_len, setup); stream_len = encode_normal(escape_sym, stream_len, setup);
...@@ -435,4 +420,3 @@ static int encode_value_multi(uint32_t data, uint32_t model, int stream_len, ...@@ -435,4 +420,3 @@ static int encode_value_multi(uint32_t data, uint32_t model, int stream_len,
return stream_len; return stream_len;
} }
#endif
...@@ -780,7 +780,7 @@ void test_encode_value_zero(void) ...@@ -780,7 +780,7 @@ void test_encode_value_zero(void)
TEST_ASSERT_EQUAL_HEX(0xFFFFFFFF, bitstream[2]); TEST_ASSERT_EQUAL_HEX(0xFFFFFFFF, bitstream[2]);
/* maximum negative value to encode */ /* maximum negative value to encode */
data = -32U; model = 0; data = 0; model = 32;
stream_len = encode_value_zero(data, model, stream_len, &setup); stream_len = encode_value_zero(data, model, stream_len, &setup);
TEST_ASSERT_EQUAL_INT(53, stream_len); TEST_ASSERT_EQUAL_INT(53, stream_len);
TEST_ASSERT_EQUAL_HEX(0xFFFFFFFE, bitstream[0]); TEST_ASSERT_EQUAL_HEX(0xFFFFFFFE, bitstream[0]);
...@@ -795,8 +795,100 @@ void test_encode_value_zero(void) ...@@ -795,8 +795,100 @@ void test_encode_value_zero(void)
setup.max_bit_len = 32; setup.max_bit_len = 32;
data = 31; model = 0; data = 31; model = 0;
stream_len = encode_value_zero(data, model, stream_len, &setup); stream_len = encode_value_zero(data, model, stream_len, &setup);
TEST_ASSERT_EQUAL_INT(-2, stream_len); TEST_ASSERT_EQUAL_INT(CMP_ERROR_SAMLL_BUF, stream_len);
TEST_ASSERT_EQUAL_HEX(0, bitstream[0]); TEST_ASSERT_EQUAL_HEX(0, bitstream[0]);
TEST_ASSERT_EQUAL_HEX(0, bitstream[1]); TEST_ASSERT_EQUAL_HEX(0, bitstream[1]);
TEST_ASSERT_EQUAL_HEX(0, bitstream[2]); TEST_ASSERT_EQUAL_HEX(0, bitstream[2]);
} }
/**
* @test encode_value_multi
*/
void test_encode_value_multi(void)
{
uint32_t data, model;
int stream_len;
struct encoder_setupt setup = {0};
uint32_t bitstream[4] = {0};
/* setup the setup */
setup.encoder_par1 = 1;
setup.encoder_par2 = (uint32_t)ilog_2(setup.encoder_par1);
setup.outlier_par = 16;
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_multi(data, model, stream_len, &setup);
TEST_ASSERT_EQUAL_INT(1, stream_len);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[0]);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[1]);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[3]);
data = 0; model = 1;
stream_len = encode_value_multi(data, model, stream_len, &setup);
TEST_ASSERT_EQUAL_INT(3, stream_len);
TEST_ASSERT_EQUAL_HEX(0x40000000, bitstream[0]);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[1]);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[3]);
data = 1+23; model = 0+23;
stream_len = encode_value_multi(data, model, stream_len, &setup);
TEST_ASSERT_EQUAL_INT(6, stream_len);
TEST_ASSERT_EQUAL_HEX(0x58000000, bitstream[0]);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[1]);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[3]);
/* highest value without multi outlier encoding */
data = 0+42; model = 8+42;
stream_len = encode_value_multi(data, model, stream_len, &setup);
TEST_ASSERT_EQUAL_INT(22, stream_len);
TEST_ASSERT_EQUAL_HEX(0x5BFFF800, bitstream[0]);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[1]);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[3]);
/* lowest value with multi outlier encoding */
data = 8+42; model = 0+42;
stream_len = encode_value_multi(data, model, stream_len, &setup);
TEST_ASSERT_EQUAL_INT(41, stream_len);
TEST_ASSERT_EQUAL_HEX(0x5BFFFBFF, bitstream[0]);
TEST_ASSERT_EQUAL_HEX(0xFC000000, bitstream[1]);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[3]);
/* highest value with multi outlier encoding */
data = INT32_MIN; model = 0;
stream_len = encode_value_multi(data, model, stream_len, &setup);
TEST_ASSERT_EQUAL_INT(105, stream_len);
TEST_ASSERT_EQUAL_HEX(0x5BFFFBFF, bitstream[0]);
TEST_ASSERT_EQUAL_HEX(0xFC7FFFFF, bitstream[1]);
TEST_ASSERT_EQUAL_HEX(0xFF7FFFFF, bitstream[2]);
TEST_ASSERT_EQUAL_HEX(0xF7800000, bitstream[3]);
/* small buffer error */
data = 0; model = 38;
stream_len = encode_value_multi(data, model, stream_len, &setup);
TEST_ASSERT_EQUAL_INT(CMP_ERROR_SAMLL_BUF, stream_len);
/* small buffer error when creating the multi escape symbol*/
bitstream[0] = 0;
bitstream[1] = 0;
setup.max_bit_len = 32;
stream_len = 32;
data = 31; model = 0;
stream_len = encode_value_multi(data, model, stream_len, &setup);
TEST_ASSERT_EQUAL_INT(CMP_ERROR_SAMLL_BUF, stream_len);
TEST_ASSERT_EQUAL_HEX(0, bitstream[0]);
TEST_ASSERT_EQUAL_HEX(0, bitstream[1]);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment