Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
cmp_tool
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Dominik Loidolt
cmp_tool
Commits
b402a986
Commit
b402a986
authored
3 years ago
by
Dominik Loidolt
Browse files
Options
Downloads
Patches
Plain Diff
refactor and test for encode_value_zero
parent
cea4951a
Branches
Branches containing commit
Tags
Tags containing commit
1 merge request
!11
decompression/compression for non-imagette data
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
lib/cmp_icu_new.c
+286
-13
286 additions, 13 deletions
lib/cmp_icu_new.c
test/cmp_icu/test_cmp_icu_new.c
+449
-20
449 additions, 20 deletions
test/cmp_icu/test_cmp_icu_new.c
with
735 additions
and
33 deletions
lib/cmp_icu_new.c
+
286
−
13
View file @
b402a986
...
...
@@ -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
This diff is collapsed.
Click to expand it.
test/cmp_icu/test_cmp_icu_new.c
+
449
−
20
View file @
b402a986
...
...
@@ -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
]
==
0x003f000
0
);
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
;
v
=
0xffffffff
;
n
=
6
;
o
=
10
;
rval
=
put_n_bits32
(
v
,
n
,
o
,
testarray0
,
l
);
TEST_ASSERT_EQUAL_INT
(
-
1
,
rval
);
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
);
/*** error cases ***/
/* n too large */
v
=
0x0
;
n
=
33
;
o
=
1
;
rval
=
put_n_bits32
(
v
,
n
,
o
,
testarray0
,
l
);
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
]);
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment