Skip to content

Commit c7704a9

Browse files
Added signed int support to bitstream (#290)
1 parent e7a7649 commit c7704a9

2 files changed

Lines changed: 42 additions & 16 deletions

File tree

middleware/include/bitstream.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ void bitstream_init(bitstream_t *bitstream, uint8_t *data, size_t bytes);
3232
int bitstream_add(bitstream_t *bitstream, uint32_t value, size_t num_bits);
3333

3434
/**
35-
* @brief Reads info from the bitstream.
36-
* @param *bitstream The bitstream to read from.
37-
* @param start_bit The bit to start reading from.
38-
* @param num_bits The amount of bits to read. The maximum is 32 bits, and (start_bit + num_bits) must be less than the total number of bits in the bitstream.
39-
* @return Returns 1 if failed, and 0 if successful.
35+
* @brief Adds a signed int to a bitstream. The data is added to the end of the bitstream.
36+
* @param *bitstream The bitstream to add data to.
37+
* @param value The data to add to the bitstream.
38+
* @param num_bits The length of the data in bits.
39+
* @return Returns 0 if successful, -1 if there is insufficient space in the bitstream, and 1 if overflow occurs.
4040
*/
41-
uint32_t bitstream_read(bitstream_t *bitstream, uint32_t start_bit,
42-
size_t num_bits);
41+
int bitstream_add_signed(bitstream_t *bitstream, int32_t value,
42+
size_t num_bits);
4343

4444
#endif // BITSTREAM_H

middleware/src/bitstream.c

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,47 @@ int bitstream_add(bitstream_t *bitstream, uint32_t value, size_t num_bits)
4040
return 0; // Success
4141
}
4242

43-
uint32_t bitstream_read(bitstream_t *bitstream, uint32_t start_bit,
44-
size_t num_bits)
43+
int bitstream_add_signed(bitstream_t *bitstream, int32_t value, size_t num_bits)
4544
{
46-
uint32_t result = 0;
45+
if (bitstream->total_bits + num_bits > (bitstream->bytes * 8)) {
46+
return -1; // Error: not enough space in the bitstream
47+
}
48+
49+
bool overflow = false;
50+
/* For a signed int, 'value' must be in between -2^(num_bits - 1) and 2^(num_bits-1) - 1. */
51+
/* For example, an 6-bit input value must be in-between -32 and 31. */
52+
int32_t max_value = (1LL << (num_bits - 1)) - 1;
53+
int32_t min_value = -(1LL << (num_bits - 1));
4754

48-
if (start_bit + num_bits > bitstream->total_bits) {
49-
return -1; // Error: trying to read beyond bit length
55+
if (value > max_value || value < min_value) {
56+
overflow = true; // Error: value is too large or too small
57+
58+
/* Cap value to maximum or minimum */
59+
if (value > max_value) {
60+
value = max_value;
61+
} else {
62+
value = min_value;
63+
}
5064
}
5165

66+
/* Create a mask for the num_bits we want to extract */
67+
uint32_t mask = (1u << num_bits) - 1;
68+
/* Extract the bits we want, including the sign bit */
69+
uint32_t bits = (uint32_t)value & mask;
70+
5271
for (int i = 0; i < num_bits; ++i) {
53-
if (bitstream->data[(start_bit + i) / 8] &
54-
(1 << (7 - ((start_bit + i) % 8)))) {
55-
result |= (1 << (num_bits - 1 - i));
72+
if (bits & (1u << (num_bits - 1 - i))) {
73+
bitstream->data[(bitstream->total_bits + i) / 8] |=
74+
(1 << (7 - ((bitstream->total_bits + i) % 8)));
5675
}
5776
}
5877

59-
return result;
78+
bitstream->total_bits += num_bits;
79+
80+
if (overflow) {
81+
bitstream->overflow = true;
82+
return 1; // Error: Overflow occurred
83+
}
84+
85+
return 0; // Success
6086
}

0 commit comments

Comments
 (0)