56 for (
size_t word = 0U; (word < bv->
num_words) && (count < max_pos); word++) {
57 uint32_t word_data = bv->
data[word];
59 while ((word_data != 0U) && (count < max_pos)) {
61 int clz = __builtin_clz(word_data);
62 size_t bit_pos_in_word = (size_t)clz;
65 size_t global_pos = (word * 32U) + bit_pos_in_word;
67 if (global_pos < bv->length) {
68 positions[count] = global_pos;
73 word_data &= ~(1U << (31U - (uint32_t)clz));
101 size_t byte_index = reader->
bit_pos / 8U;
102 size_t bit_index = reader->
bit_pos % 8U;
105 uint8_t shifted = reader->
data[byte_index] >> (7U - bit_index);
106 uint8_t masked = shifted & 1U;
107 result = (int)masked;
118 if ((reader != NULL) && (num_bits <= 32U)) {
124 for (
size_t i = 0U; i < num_bits; i++) {
127 value = (value << 1U) | ((uint32_t)bit & 1U);
139 if (reader != NULL) {
148 size_t remaining = 0U;
159 if (reader != NULL) {
160 size_t bit_offset = reader->
bit_pos % 8U;
161 if (bit_offset != 0U) {
162 reader->
bit_pos += (8U - bit_offset);
178 if ((reader == NULL) || (value == NULL)) {
226 }
while (next_bit == 0);
229 size_t value_bits = size + 5U;
254 if ((reader == NULL) || (result == NULL)) {
263 size_t bit_position = length;
271 if (delta > bit_position) {
275 bit_position -= delta;
290 if ((reader == NULL) || (data == NULL) || (mask == NULL)) {
315 for (
size_t i = pos_count; i > 0U; i--) {
341 if (decomp == NULL) {
364 if (initial_mask != NULL) {
390 if (decomp != NULL) {
413 if (decomp == NULL) {
417 if (lost_count == 0U) {
433 decomp->
t += lost_count;
449 for (uint32_t i = 0U; i < lost_count; i++) {
497 if ((decomp == NULL) || (reader == NULL) || (output == NULL)) {
526 uint8_t Vt = (uint8_t)(vt_raw & 0x0FU);
532 if ((Vt > 0U) && (change_count > 0U)) {
552 for (
size_t idx = 0U; idx < num_changes; idx++) {
557 kt_bits[idx] = (bit_val > 0) ? 1U : 0U;
561 for (
size_t idx = 0U; idx < num_changes; idx++) {
562 size_t pos = change_positions[idx];
565 if (kt_bits[idx] != 0U) {
580 for (
size_t idx = 0U; idx < num_changes; idx++) {
584 }
else if ((Vt == 0U) && (change_count > 0U)) {
590 for (
size_t idx = 0U; idx < num_changes; idx++) {
591 size_t pos = change_positions[idx];
594 if (current_val == 0) {
654 for (
size_t i = decomp->
F - 1U; i > 0U; i--) {
658 current = hxor_bit ^ current;
679 flags->
ft = (ft != 0) ? 1U : 0U;
680 flags->
rt = (rt != 0) ? 1U : 0U;
685 uint32_t packet_length = 0U;
694 if (packet_length != (uint32_t)decomp->
F) {
702 for (
size_t i = 0U; i < decomp->
F; i++) {
714 if ((ct == 1) && (Vt > 0U)) {
756 if ((decomp == NULL) || (data == NULL) || (output == NULL)) {
760 if (num_bits == 0U) {
768 (void)memcpy(&saved_decomp, decomp,
sizeof(*decomp));
789 (void)memcpy(decomp, &saved_decomp,
sizeof(*decomp));
799 if (result != NULL) {
809 uint8_t mask_inconsistent_detected = ((decomp->
mask_synced != 0U) &&
811 uint8_t count_f_mismatch_detected = (decomp->
count_f_mismatch != 0U) ? 1U : 0U;
814 if (mask_inconsistent_detected != 0U) {
816 }
else if (count_f_mismatch_detected != 0U) {
818 }
else if (flags.
rt == 1U) {
835 while ((checked < (
size_t)flags.
Vt) && (ring_walk > 0U)) {
860 if (guaranteed != 0U) {
865 if (flags.
ft == 1U) {
868 }
else if (mask_inconsistent_detected != 0U) {
870 (void)memcpy(decomp, &saved_decomp,
sizeof(*decomp));
874 }
else if (count_f_mismatch_detected != 0U) {
878 if (flags.
ft == 1U) {
883 (void)memcpy(decomp, &saved_decomp,
sizeof(*decomp));
897 if (result != NULL) {
898 result->
status = out_status;
899 result->
Vt = flags.
Vt;
900 result->
ft = flags.
ft;
901 result->
rt = flags.
rt;
936 uint32_t count_val = 0U;
941 total += (uint64_t)count_val;
946 *hamming_weight = hw;
957 uint32_t *packet_length
959 if ((data == NULL) || (packet_length == NULL)) {
963 if (num_bits == 0U) {
975 uint64_t Xt_span = 0U;
987 if ((H_Xt > 0U) && (Vt > 0U)) {
997 for (uint32_t i = 0U; i < H_Xt; i++) {
1026 uint64_t mask_span = 0U;
1029 uint32_t mask_hw = 0U;
1047 uint32_t discovered_F = 0U;
1049 if ((rc !=
CCSDS124_OK) || (discovered_F == 0U)) {
1058 if ((discovered_F > 65535U) ||
1059 (Xt_span > (uint64_t)discovered_F) ||
1060 (mask_span > (uint64_t)discovered_F)) {
1071 *packet_length = discovered_F;
1078 *packet_length = discovered_F;
1085 const uint8_t *input_data,
1087 uint8_t *output_buffer,
1088 size_t output_buffer_size,
1091 if ((decomp == NULL) || (input_data == NULL) ||
1092 (output_buffer == NULL) || (output_size == NULL)) {
1104 size_t packet_bytes = (decomp->
F + 7U) / 8U;
1105 size_t total_output = 0U;
1116 if ((total_output + packet_bytes) > output_buffer_size) {
1122 total_output += packet_bytes;
1128 *output_size = total_output;
CCSDS 124.0-B-1 Compression Library - Public API.
static int ccsds124_decompress_packet_internal(ccsds124_decompressor_t *decomp, bitreader_t *reader, bitvector_t *output, ccsds124_decompress_flags_t *flags)
Internal decompression with optional flag extraction.
static int skip_rle_sequence_span(bitreader_t *reader, uint32_t *hamming_weight, uint64_t *span)
Skip COUNT values in an RLE sequence until the terminator.
static size_t bitvector_get_set_positions(const bitvector_t *bv, size_t *positions, size_t max_pos)
Extract positions of all set bits in a bitvector using word-level processing.
size_t bitreader_position(const bitreader_t *reader)
Get current bit position.
void bitreader_align_byte(bitreader_t *reader)
Skip to next byte boundary.
int bitreader_read_bit(bitreader_t *reader)
Read a single bit.
uint32_t bitreader_read_bits(bitreader_t *reader, size_t num_bits)
Read multiple bits as unsigned value.
size_t bitreader_remaining(const bitreader_t *reader)
Get remaining bits.
void bitreader_init(bitreader_t *reader, const uint8_t *data, size_t num_bits)
Initialize bit reader.
void bitvector_copy(bitvector_t *dest, const bitvector_t *src)
Copy bit vector contents.
int bitvector_to_bytes(const bitvector_t *bv, uint8_t *data, size_t num_bytes)
Store bit vector to byte array.
size_t bitvector_hamming_weight(const bitvector_t *bv)
Count number of set bits (Hamming weight).
static void bitvector_set_bit(bitvector_t *bv, size_t pos, int value)
Set bit value at position (inline for performance).
int bitvector_init(bitvector_t *bv, size_t num_bits)
Initialize a bit vector with specified length.
static int bitvector_get_bit(const bitvector_t *bv, size_t pos)
Get bit value at position (inline for performance).
int bitvector_equals(const bitvector_t *a, const bitvector_t *b)
Compare two bit vectors for equality.
void bitvector_zero(bitvector_t *bv)
Set all bits to zero.
void bitvector_or(bitvector_t *result, const bitvector_t *a, const bitvector_t *b)
Bitwise OR operation.
#define CCSDS124_MAX_VT_HISTORY
#define CCSDS124_MAX_PACKET_LENGTH
#define CCSDS124_MAX_ROBUSTNESS
int ccsds124_rle_decode(bitreader_t *reader, bitvector_t *result, size_t length)
Run-length decoding (inverse of ccsds124_rle_encode).
int ccsds124_count_decode(bitreader_t *reader, uint32_t *value)
Counter decoding (inverse of ccsds124_count_encode).
int ccsds124_bit_insert(bitreader_t *reader, bitvector_t *data, const bitvector_t *mask)
Bit insertion (inverse of ccsds124_bit_extract).
int ccsds124_decompress_packet(ccsds124_decompressor_t *decomp, bitreader_t *reader, bitvector_t *output)
Decompress a single compressed packet.
void ccsds124_decompressor_reset(ccsds124_decompressor_t *decomp)
Reset decompressor to initial state.
int ccsds124_decompress_packet_checked(ccsds124_decompressor_t *decomp, const uint8_t *data, size_t num_bits, bitvector_t *output, ccsds124_decompress_result_t *result)
Decompress a single packet with accuracy guarantee checking.
int ccsds124_decompress(ccsds124_decompressor_t *decomp, const uint8_t *input_data, size_t input_size, uint8_t *output_buffer, size_t output_buffer_size, size_t *output_size)
Decompress entire compressed data stream.
int ccsds124_discover_packet_length(const uint8_t *data, size_t num_bits, uint32_t *packet_length)
Discover packet length (F) from a compressed packet.
int ccsds124_decompressor_notify_packet_loss(ccsds124_decompressor_t *decomp, uint32_t lost_count)
Notify decompressor of packet loss.
int ccsds124_decompressor_init(ccsds124_decompressor_t *decomp, size_t F, const bitvector_t *initial_mask, uint8_t robustness)
Initialize decompressor state.
#define CCSDS124_ERROR_OVERFLOW
#define CCSDS124_ERROR_INVALID_ARG
#define CCSDS124_ERROR_UNDERFLOW
#define CCSDS124_STATUS_TRUNCATED_LENGTH
#define CCSDS124_STATUS_UNGUARANTEED
Bit reader structure for sequential reading.
Fixed-length bit vector structure.
uint32_t data[((CCSDS124_MAX_PACKET_BYTES)+3U)/4U]
Internal flags extracted during decompression.
Decompression result with accuracy guarantee status.
Decompressor state structure.
uint8_t mask_inconsistent
uint8_t received_status_index
uint8_t received_status_ring[CCSDS124_MAX_VT_HISTORY]
uint8_t received_status_count