CCSDS 124.0-B-1 C 1.0.0
CCSDS 124.0-B-1 Lossless Compression
Loading...
Searching...
No Matches
compress.c
Go to the documentation of this file.
1
27#include "ccsds124.h"
28#include <string.h>
29
38 size_t F,
39 const bitvector_t *initial_mask,
40 uint8_t robustness,
41 int pt_limit,
42 int ft_limit,
43 int rt_limit
44) {
45 int result = CCSDS124_ERROR_INVALID_ARG;
46
47 if (comp != NULL) {
48 if ((F == 0U) || (F > (size_t)CCSDS124_MAX_PACKET_LENGTH)) {
49 /* Invalid packet length - result already set */
50 } else if (robustness > (uint8_t)CCSDS124_MAX_ROBUSTNESS) {
51 /* Invalid robustness - result already set */
52 } else {
53 /* Store configuration */
54 comp->F = F;
55 comp->robustness = robustness;
56 comp->pt_limit = pt_limit;
57 comp->ft_limit = ft_limit;
58 comp->rt_limit = rt_limit;
59
60 /* Initialize all bit vectors */
61 (void)bitvector_init(&comp->mask, F);
62 (void)bitvector_init(&comp->prev_mask, F);
63 (void)bitvector_init(&comp->build, F);
64 (void)bitvector_init(&comp->prev_input, F);
65 (void)bitvector_init(&comp->initial_mask, F);
66
67 /* Initialize change history */
68 for (size_t i = 0U; i < CCSDS124_MAX_HISTORY; i++) {
69 (void)bitvector_init(&comp->change_history[i], F);
71 }
72
73 /* Initialize flag history for cₜ calculation */
74 for (size_t i = 0U; i < CCSDS124_MAX_VT_HISTORY; i++) {
75 comp->new_mask_flag_history[i] = 0U;
76 }
77 comp->flag_history_index = 0;
78
79 /* Set initial mask */
80 if (initial_mask != NULL) {
81 bitvector_copy(&comp->initial_mask, initial_mask);
82 bitvector_copy(&comp->mask, initial_mask);
83 } else {
85 bitvector_zero(&comp->mask);
86 }
87
88 /* Initialize work buffers (pre-allocated to avoid per-packet init) */
89 (void)bitvector_init(&comp->work_prev_build, F);
90 (void)bitvector_init(&comp->work_change, F);
91 (void)bitvector_init(&comp->work_Xt, F);
92 (void)bitvector_init(&comp->work_inverted, F);
93 (void)bitvector_init(&comp->work_shifted, F);
94 (void)bitvector_init(&comp->work_diff, F);
95
96 /* Reset state */
98
99 result = CCSDS124_OK;
100 }
101 }
102
103 return result;
104}
105
106
108 if (comp != NULL) {
109 /* Reset time index */
110 comp->t = 0U;
111 comp->history_index = 0U;
112
113 /* Reset mask to initial */
114 bitvector_copy(&comp->mask, &comp->initial_mask);
116
117 /* Clear build and prev_input */
118 bitvector_zero(&comp->build);
120
121 /* Clear change history */
122 for (size_t i = 0U; i < CCSDS124_MAX_HISTORY; i++) {
124 }
125
126 /* Reset countdown counters (match reference implementation behavior) */
127 comp->pt_counter = comp->pt_limit;
128 comp->ft_counter = comp->ft_limit;
129 comp->rt_counter = comp->rt_limit;
130 }
131}
132
/* End of Compressor Initialization */
134
152 ccsds124_params_t *params,
153 const ccsds124_compressor_t *comp
154) {
155 /* Default parameters */
156 params->min_robustness = comp->robustness;
157 params->new_mask_flag = 0;
158 params->send_mask_flag = 0;
159 params->uncompressed_flag = 0;
160
161 /* Note: Caller should handle CCSDS initialization requirements
162 * (ft=1, rt=1 for first Rt+1 packets) */
163}
164
/* End of Internal Helper Functions */
166
174 bitvector_t *Xt,
175 const ccsds124_compressor_t *comp,
176 const bitvector_t *current_change
177) {
178 /* Xₜ = <(Dₜ₋ᴿₜ OR Dₜ₋ᴿₜ₊₁ OR ... OR Dₜ)>
179 * Where <a> means reverse the bit order */
180
181 /* Use Xt directly as accumulator to avoid stack allocations */
182 Xt->length = comp->F;
183 Xt->num_words = (((comp->F + 7U) / 8U) + 3U) / 4U;
184
185 if ((comp->robustness == 0U) || (comp->t == 0U)) {
186 /* Xₜ = Dₜ (no reversal - RLE processes LSB to MSB directly) */
187 bitvector_copy(Xt, current_change);
188 } else {
189 /* Start with current change, accumulate OR directly into Xt */
190 bitvector_copy(Xt, current_change);
191
192 /* Determine how many historical changes to include */
193 size_t num_changes = (comp->t < (size_t)comp->robustness) ? comp->t : (size_t)comp->robustness;
194
195 /* OR with historical changes (going backwards from current)
196 * Use in-place OR: Xt = Xt OR history[i] */
197 for (size_t i = 1U; i <= num_changes; i++) {
198 size_t hist_idx = ((comp->history_index + (size_t)CCSDS124_MAX_HISTORY) - i) % (size_t)CCSDS124_MAX_HISTORY;
199 const bitvector_t *hist = &comp->change_history[hist_idx];
200
201 /* In-place OR at word level */
202 for (size_t w = 0U; w < Xt->num_words; w++) {
203 Xt->data[w] |= hist->data[w];
204 }
205 }
206 }
207}
208
209
211 const ccsds124_compressor_t *comp,
212 const bitvector_t *current_change
213) {
214 /* Vₜ = Rₜ + Cₜ (CCSDS Section 5.3.2.2)
215 * where Cₜ = number of consecutive iterations with no mask changes
216 *
217 * For t ≤ Rt: Vt = Rt
218 * For t > Rt: Vt = Rt + Ct */
219
220 (void)current_change; /* Unused - Ct is computed from history */
221
222 uint8_t Rt = comp->robustness;
223 uint8_t Vt = Rt;
224
225 /* For t > Rt, compute Ct */
226 if (comp->t > (size_t)Rt) {
227 /* Count backwards through history starting from Rt+1 positions back
228 * (matching reference: start = pt_history_index + Rt + 1) */
229 uint8_t Ct = 0U;
230 int done = 0;
231
232 for (size_t i = (size_t)Rt + 1U; (i <= 15U) && (i <= comp->t) && (done == 0); i++) {
233 size_t hist_idx = ((comp->history_index + (size_t)CCSDS124_MAX_HISTORY) - i) % (size_t)CCSDS124_MAX_HISTORY;
234 if (bitvector_hamming_weight(&comp->change_history[hist_idx]) > 0U) {
235 done = 1; /* Found a change, stop counting */
236 } else {
237 Ct++;
238 if (Ct >= (15U - Rt)) {
239 done = 1; /* Cap at maximum Ct value */
240 }
241 }
242 }
243
244 Vt = Rt + Ct;
245 if (Vt > 15U) {
246 Vt = 15U; /* Cap at 15 (4 bits) */
247 }
248 }
249
250 return Vt;
251}
252
253
255 const bitvector_t *Xt,
256 const bitvector_t *mask
257) {
258 int result = 0; /* No positive updates by default */
259
260 /* eₜ = 1 if any changed bits (in Xₜ) are predictable (mask bit = 0)
261 * This is equivalent to: (Xt AND (NOT mask)) != 0
262 * Use word-level operations for efficiency */
263
264 if ((Xt != NULL) && (mask != NULL)) {
265 size_t num_words = Xt->num_words;
266 if (mask->num_words < num_words) {
267 num_words = mask->num_words;
268 }
269
270 for (size_t i = 0U; (i < num_words) && (result == 0); i++) {
271 /* Check if any bit in Xt is set where mask is clear */
272 if ((Xt->data[i] & ~mask->data[i]) != 0U) {
273 result = 1;
274 }
275 }
276 }
277
278 return result;
279}
280
281
283 const ccsds124_compressor_t *comp,
284 uint8_t Vt,
285 int current_new_mask_flag
286) {
287 int result = 0;
288
289 /* cₜ = 1 if new_mask_flag was set 2+ times in last Vₜ+1 iterations
290 * (including current packet) - matches reference implementation */
291
292 if (Vt != 0U) {
293 /* Count how many times new_mask_flag was set.
294 * Reference checks from current (i=pt_history_index) to current+Vt,
295 * which is Vt+1 entries including current packet */
296 int count = 0;
297
298 /* Include current packet's flag */
299 if (current_new_mask_flag != 0) {
300 count++;
301 }
302
303 /* Check history for Vt previous entries */
304 size_t iterations_to_check = ((size_t)Vt <= comp->t) ? (size_t)Vt : comp->t;
305
306 for (size_t i = 0U; i < iterations_to_check; i++) {
307 /* Calculate history index going backwards from previous */
308 size_t hist_idx = ((comp->flag_history_index + (size_t)CCSDS124_MAX_VT_HISTORY) - 1U - i) % (size_t)CCSDS124_MAX_VT_HISTORY;
309 if (comp->new_mask_flag_history[hist_idx] != 0U) {
310 count++;
311 }
312 }
313
314 if (count >= 2) {
315 result = 1;
316 }
317 }
318
319 return result;
320}
321
/* End of CCSDS Helper Functions */
323
332 const bitvector_t *input,
333 bitbuffer_t *output,
334 const ccsds124_params_t *params
335) {
336 int result = CCSDS124_ERROR_INVALID_ARG;
337
338 if ((comp == NULL) || (input == NULL) || (output == NULL)) {
339 /* Invalid arguments - result already set */
340 } else if (input->length != comp->F) {
341 /* Invalid input length - result already set */
342 } else {
343 /* Get parameters (use defaults if NULL) */
344 ccsds124_params_t local_params;
345 const ccsds124_params_t *effective_params = params;
346 if (params == NULL) {
347 get_default_params(&local_params, comp);
348 effective_params = &local_params;
349 }
350
351 /* Clear output buffer */
352 bitbuffer_clear(output);
353
354 /* ====================================================================
355 * STEP 1: Update Mask and Build Vectors (CCSDS Section 4)
356 * ==================================================================== */
357
358 /* Use pre-allocated prev_mask from struct */
359 bitvector_copy(&comp->prev_mask, &comp->mask);
360
361 /* Use pre-allocated work buffer for prev_build */
362 bitvector_copy(&comp->work_prev_build, &comp->build);
363
364 /* Update build vector (Equation 6) */
365 if (comp->t > 0U) {
366 ccsds124_update_build(&comp->build, input, &comp->prev_input,
367 effective_params->new_mask_flag, comp->t);
368 }
369
370 /* Update mask vector (Equation 7) */
371 if (comp->t > 0U) {
372 ccsds124_update_mask(&comp->mask, input, &comp->prev_input,
373 &comp->work_prev_build, effective_params->new_mask_flag);
374 }
375
376 /* Compute change vector (Equation 8) - use pre-allocated work buffer */
377 ccsds124_compute_change(&comp->work_change, &comp->mask, &comp->prev_mask, comp->t);
378
379 /* Store change in history (circular buffer) */
381
382 /* ====================================================================
383 * STEP 2: Encode Output Packet (CCSDS Section 5.3)
384 * oₜ = hₜ ∥ qₜ ∥ uₜ
385 * Full CCSDS encoding per ALGORITHM.md
386 * ==================================================================== */
387
388 /* Calculate Xₜ (robustness window) - use pre-allocated work buffer */
390
391 /* Calculate Vₜ (effective robustness) */
392 uint8_t Vt = ccsds124_compute_effective_robustness(comp, &comp->work_change);
393
394 /* Calculate ḋₜ flag */
395 uint8_t dt = ((effective_params->send_mask_flag == 0U) && (effective_params->uncompressed_flag == 0U)) ? 1U : 0U;
396
397 /* ====================================================================
398 * Component hₜ: Mask change information
399 * hₜ = RLE(Xₜ) ∥ BIT₄(Vₜ) ∥ eₜ ∥ kₜ ∥ cₜ ∥ ḋₜ
400 * ==================================================================== */
401
402 /* 1. RLE(Xₜ) - Run-length encode the robustness window */
403 (void)ccsds124_rle_encode(output, &comp->work_Xt);
404
405 /* 2. BIT₄(Vₜ) - 4-bit effective robustness level
406 * CCSDS encodes Vt directly (reference implementation confirmed) */
407 for (int i = 3; i >= 0; i--) {
408 uint32_t vt_shifted = (uint32_t)Vt >> (uint32_t)i;
409 uint32_t vt_masked = vt_shifted & 1U;
410 int bit_val = (int)vt_masked;
411 (void)bitbuffer_append_bit(output, bit_val);
412 }
413
414 /* 3. eₜ, kₜ, cₜ - Only if Vₜ > 0 and there are mask changes */
415 if ((Vt > 0U) && (bitvector_hamming_weight(&comp->work_Xt) > 0U)) {
416 /* Calculate eₜ */
417 int et = ccsds124_has_positive_updates(&comp->work_Xt, &comp->mask);
418
419 (void)bitbuffer_append_bit(output, et);
420
421 if (et != 0) {
422 /* kₜ - Output '1' for positive updates (mask=0), '0' for negative updates (mask=1)
423 * Reference implementation shows kt outputs 1 when mask bit is 0 at changed positions */
424
425 /* Extract INVERTED mask values (1 where mask=0, 0 where mask=1)
426 * Use pre-allocated work buffer for inverted mask */
427 bitvector_not(&comp->work_inverted, &comp->mask);
428
429 (void)ccsds124_bit_extract_forward(output, &comp->work_inverted, &comp->work_Xt);
430
431 /* Calculate and encode cₜ */
432 int ct = ccsds124_compute_ct_flag(comp, Vt, effective_params->new_mask_flag);
433
434 (void)bitbuffer_append_bit(output, ct);
435 }
436 }
437
438 /* 4. ḋₜ - Flag indicating if both ḟₜ and ṙₜ are zero */
439 (void)bitbuffer_append_bit(output, (int)dt);
440
441 /* ====================================================================
442 * Component qₜ: Optional full mask
443 * qₜ = ∅ if ḋₜ=1, '1' ∥ RLE(<(Mₜ XOR (Mₜ≪))>) if ḟₜ=1, '0' otherwise
444 * ==================================================================== */
445
446 if (dt == 0U) { /* Only if ḋₜ = 0 */
447 if (effective_params->send_mask_flag != 0U) {
448 (void)bitbuffer_append_bit(output, 1); /* Flag: mask follows */
449
450 /* Encode mask as RLE(M XOR (M<<)) - use pre-allocated work buffers */
451 bitvector_left_shift(&comp->work_shifted, &comp->mask);
452 bitvector_xor(&comp->work_diff, &comp->mask, &comp->work_shifted);
453
454 (void)ccsds124_rle_encode(output, &comp->work_diff);
455 } else {
456 (void)bitbuffer_append_bit(output, 0); /* Flag: no mask */
457 }
458 }
459
460 /* ====================================================================
461 * Component uₜ: Unpredictable bits or full input
462 * Per ALGORITHM.md, depends on ḋₜ, ṙₜ, cₜ
463 * ==================================================================== */
464
465 if (effective_params->uncompressed_flag != 0U) {
466 /* '1' ∥ COUNT(F) ∥ Iₜ */
467 (void)bitbuffer_append_bit(output, 1); /* Flag: full input follows */
468
469 (void)ccsds124_count_encode(output, (uint32_t)comp->F);
470
471 (void)bitbuffer_append_bitvector(output, input);
472 } else {
473 if (dt == 0U) {
474 /* '0' ∥ BE(...) */
475 (void)bitbuffer_append_bit(output, 0); /* Flag: compressed */
476 }
477
478 /* Determine extraction mask based on cₜ */
479 int ct = ccsds124_compute_ct_flag(comp, Vt, effective_params->new_mask_flag);
480
481 if ((ct != 0) && (Vt > 0U)) {
482 /* BE(Iₜ, (Xₜ OR Mₜ)) - extract bits where mask OR changes are set
483 * Reuse work_diff as extraction mask (not used at this point) */
484 bitvector_or(&comp->work_diff, &comp->mask, &comp->work_Xt); /* Mₜ OR Xₜ */
485
486 (void)ccsds124_bit_extract(output, input, &comp->work_diff);
487 } else {
488 /* BE(Iₜ, Mₜ) - extract only unpredictable bits */
489 (void)ccsds124_bit_extract(output, input, &comp->mask);
490 }
491 }
492
493 /* ====================================================================
494 * STEP 3: Update State for Next Cycle
495 * ==================================================================== */
496
497 /* Save current input and mask as previous for next iteration */
498 bitvector_copy(&comp->prev_input, input);
499 bitvector_copy(&comp->prev_mask, &comp->mask);
500
501 /* Track new_mask_flag for cₜ calculation */
502 comp->new_mask_flag_history[comp->flag_history_index] = effective_params->new_mask_flag;
504
505 /* Advance time */
506 comp->t++;
507
508 /* Advance history index (circular buffer) */
509 comp->history_index = (comp->history_index + 1U) % (size_t)CCSDS124_MAX_HISTORY;
510
511 result = CCSDS124_OK;
512 }
513
514 return result;
515}
516
517
520 const uint8_t *input_data,
521 size_t input_size,
522 uint8_t *output_buffer,
523 size_t output_buffer_size,
524 size_t *output_size
525) {
526 int result = CCSDS124_ERROR_INVALID_ARG;
527
528 if ((comp == NULL) || (input_data == NULL) || (output_buffer == NULL) || (output_size == NULL)) {
529 /* Invalid arguments - result already set */
530 } else {
531 /* Calculate packet size in bytes */
532 size_t packet_size_bytes = (comp->F + 7U) / 8U;
533
534 /* Verify input size is a multiple of packet size */
535 if ((input_size % packet_size_bytes) != 0U) {
536 /* Invalid input size - result already set */
537 } else {
538 /* Calculate number of packets */
539 size_t num_packets = input_size / packet_size_bytes;
540
541 /* Reset compressor state */
543
544 /* Output accumulation */
545 size_t total_output_bytes = 0U;
546 int compress_error = 0;
547
548 /* Process each packet */
549 for (size_t i = 0U; (i < num_packets) && (compress_error == 0); i++) {
550 bitvector_t input_vec;
551 bitbuffer_t packet_output;
552
553 (void)bitvector_init(&input_vec, comp->F);
554 bitbuffer_init(&packet_output);
555
556 /* Load packet data */
557 (void)bitvector_from_bytes(&input_vec, &input_data[i * packet_size_bytes], packet_size_bytes);
558
559 /* Compute parameters */
560 ccsds124_params_t params;
561 params.min_robustness = comp->robustness;
562
563 /* If limits are set, manage parameters automatically using countdown counters
564 * (matches reference implementation exactly) */
565 if ((comp->pt_limit > 0) && (comp->ft_limit > 0) && (comp->rt_limit > 0)) {
566 /* Reference implementation: packet 1 handled separately, loop starts at packet 2 (1-indexed).
567 * In 0-indexed: packet 0 = handled separately, counters start at packet 1. */
568 if (i == 0U) {
569 /* First packet: fixed init values, counters not checked */
570 params.send_mask_flag = 1;
571 params.uncompressed_flag = 1;
572 params.new_mask_flag = 0;
573 } else {
574 /* Packets 1+: check and update countdown counters */
575 /* ft counter */
576 if (comp->ft_counter == 1) {
577 params.send_mask_flag = 1;
578 comp->ft_counter = comp->ft_limit;
579 } else {
580 comp->ft_counter--;
581 params.send_mask_flag = 0;
582 }
583
584 /* pt counter */
585 if (comp->pt_counter == 1) {
586 params.new_mask_flag = 1;
587 comp->pt_counter = comp->pt_limit;
588 } else {
589 comp->pt_counter--;
590 params.new_mask_flag = 0;
591 }
592
593 /* rt counter */
594 if (comp->rt_counter == 1) {
595 params.uncompressed_flag = 1;
596 comp->rt_counter = comp->rt_limit;
597 } else {
598 comp->rt_counter--;
599 params.uncompressed_flag = 0;
600 }
601
602 /* Override for remaining init packets: CCSDS requires first Rt+1 packets
603 * to have ft=1, rt=1, pt=0. Reference checks: if (i < Rt+2) in 1-indexed.
604 * In 0-indexed: if (i <= Rt). Counters are still decremented per reference. */
605 if (i <= (size_t)comp->robustness) {
606 params.send_mask_flag = 1;
607 params.uncompressed_flag = 1;
608 params.new_mask_flag = 0;
609 }
610 }
611 } else {
612 /* Manual control: use defaults (ft=0, rt=0, pt=0 for normal operation) */
613 params.send_mask_flag = 0;
614 params.uncompressed_flag = 0;
615 params.new_mask_flag = 0;
616 }
617
618 /* Compress packet */
619 int packet_result = ccsds124_compress_packet(comp, &input_vec, &packet_output, &params);
620 if (packet_result != CCSDS124_OK) {
621 result = packet_result;
622 compress_error = 1;
623 } else {
624 /* Convert packet to bytes with byte-boundary padding */
625 uint8_t packet_bytes[CCSDS124_MAX_OUTPUT_BYTES];
626 size_t packet_size = bitbuffer_to_bytes(&packet_output, packet_bytes, sizeof(packet_bytes));
627
628 /* Check if output buffer has space */
629 if ((total_output_bytes + packet_size) > output_buffer_size) {
631 compress_error = 1;
632 } else {
633 /* Append to output buffer */
634 (void)memcpy(&output_buffer[total_output_bytes], packet_bytes, packet_size);
635 total_output_bytes += packet_size;
636 }
637 }
638 }
639
640 /* Return total output size if successful */
641 if (compress_error == 0) {
642 *output_size = total_output_bytes;
643 result = CCSDS124_OK;
644 }
645 }
646 }
647
648 return result;
649}
650
/* End of Main Compression Functions */
CCSDS 124.0-B-1 Compression Library - Public API.
static void get_default_params(ccsds124_params_t *params, const ccsds124_compressor_t *comp)
Get default compression parameters.
Definition compress.c:151
int bitbuffer_append_bitvector(bitbuffer_t *bb, const bitvector_t *bv)
Append all bits from a bit vector.
Definition bitbuffer.c:181
int bitbuffer_append_bit(bitbuffer_t *bb, int bit)
Append a single bit to buffer.
Definition bitbuffer.c:77
void bitbuffer_clear(bitbuffer_t *bb)
Clear bit buffer contents.
Definition bitbuffer.c:50
void bitbuffer_init(bitbuffer_t *bb)
Initialize bit buffer to empty state.
Definition bitbuffer.c:40
size_t bitbuffer_to_bytes(const bitbuffer_t *bb, uint8_t *data, size_t max_bytes)
Convert bit buffer to byte array.
Definition bitbuffer.c:244
void bitvector_copy(bitvector_t *dest, const bitvector_t *src)
Copy bit vector contents.
Definition bitvector.c:72
int bitvector_from_bytes(bitvector_t *bv, const uint8_t *data, size_t num_bytes)
Load bit vector from byte array.
Definition bitvector.c:269
void bitvector_xor(bitvector_t *result, const bitvector_t *a, const bitvector_t *b)
Bitwise XOR operation.
Definition bitvector.c:93
size_t bitvector_hamming_weight(const bitvector_t *bv)
Count number of set bits (Hamming weight).
Definition bitvector.c:222
int bitvector_init(bitvector_t *bv, size_t num_bits)
Initialize a bit vector with specified length.
Definition bitvector.c:44
void bitvector_not(bitvector_t *result, const bitvector_t *a)
Bitwise NOT operation.
Definition bitvector.c:144
void bitvector_zero(bitvector_t *bv)
Set all bits to zero.
Definition bitvector.c:65
void bitvector_left_shift(bitvector_t *result, const bitvector_t *a)
Left shift by one bit.
Definition bitvector.c:178
void bitvector_or(bitvector_t *result, const bitvector_t *a, const bitvector_t *b)
Bitwise OR operation.
Definition bitvector.c:110
int ccsds124_compressor_init(ccsds124_compressor_t *comp, size_t F, const bitvector_t *initial_mask, uint8_t robustness, int pt_limit, int ft_limit, int rt_limit)
Initialize compressor state.
Definition compress.c:36
int ccsds124_compress_packet(ccsds124_compressor_t *comp, const bitvector_t *input, bitbuffer_t *output, const ccsds124_params_t *params)
Compress a single input packet.
Definition compress.c:330
uint8_t ccsds124_compute_effective_robustness(const ccsds124_compressor_t *comp, const bitvector_t *current_change)
Compute effective robustness Vₜ.
Definition compress.c:210
void ccsds124_compute_robustness_window(bitvector_t *Xt, const ccsds124_compressor_t *comp, const bitvector_t *current_change)
Compute robustness window Xₜ.
Definition compress.c:173
void ccsds124_compressor_reset(ccsds124_compressor_t *comp)
Reset compressor to initial state.
Definition compress.c:107
int ccsds124_compute_ct_flag(const ccsds124_compressor_t *comp, uint8_t Vt, int current_new_mask_flag)
Compute cₜ flag for multiple mask updates.
Definition compress.c:282
int ccsds124_compress(ccsds124_compressor_t *comp, const uint8_t *input_data, size_t input_size, uint8_t *output_buffer, size_t output_buffer_size, size_t *output_size)
Compress entire input data stream.
Definition compress.c:518
int ccsds124_has_positive_updates(const bitvector_t *Xt, const bitvector_t *mask)
Check for positive mask updates (eₜ flag).
Definition compress.c:254
#define CCSDS124_MAX_HISTORY
Definition ccsds124.h:71
#define CCSDS124_MAX_VT_HISTORY
Definition ccsds124.h:72
#define CCSDS124_MAX_PACKET_LENGTH
Definition ccsds124.h:66
#define CCSDS124_MAX_ROBUSTNESS
Definition ccsds124.h:70
#define CCSDS124_MAX_OUTPUT_BYTES
Definition ccsds124.h:74
int ccsds124_bit_extract_forward(bitbuffer_t *output, const bitvector_t *data, const bitvector_t *mask)
Bit extraction in forward order (LSB to MSB).
Definition encode.c:273
int ccsds124_bit_extract(bitbuffer_t *output, const bitvector_t *data, const bitvector_t *mask)
Bit extraction (CCSDS Section 5.2.4, Equation 11).
Definition encode.c:220
int ccsds124_rle_encode(bitbuffer_t *output, const bitvector_t *input)
Run-length encoding (CCSDS Section 5.2.3, Equation 10).
Definition encode.c:135
int ccsds124_count_encode(bitbuffer_t *output, uint32_t A)
Counter encoding (CCSDS Section 5.2.2, Equation 9).
Definition encode.c:40
#define CCSDS124_ERROR_OVERFLOW
Definition ccsds124.h:49
#define CCSDS124_ERROR_INVALID_ARG
Definition ccsds124.h:48
#define CCSDS124_OK
Definition ccsds124.h:47
void ccsds124_compute_change(bitvector_t *change, const bitvector_t *mask, const bitvector_t *prev_mask, size_t t)
Compute change vector (CCSDS Equation 8).
Definition mask.c:125
void ccsds124_update_build(bitvector_t *build, const bitvector_t *input, const bitvector_t *prev_input, int new_mask_flag, size_t t)
Update build vector (CCSDS Equation 6).
Definition mask.c:43
void ccsds124_update_mask(bitvector_t *mask, const bitvector_t *input, const bitvector_t *prev_input, const bitvector_t *build_prev, int new_mask_flag)
Update mask vector (CCSDS Equation 7).
Definition mask.c:85
Variable-length bit buffer structure.
Definition ccsds124.h:308
Fixed-length bit vector structure.
Definition ccsds124.h:133
size_t num_words
Definition ccsds124.h:136
size_t length
Definition ccsds124.h:135
uint32_t data[((CCSDS124_MAX_PACKET_BYTES)+3U)/4U]
Definition ccsds124.h:134
Compressor state structure.
Definition ccsds124.h:537
bitvector_t work_prev_build
Definition ccsds124.h:578
uint8_t new_mask_flag_history[CCSDS124_MAX_VT_HISTORY]
Definition ccsds124.h:557
bitvector_t work_shifted
Definition ccsds124.h:582
bitvector_t work_change
Definition ccsds124.h:579
bitvector_t work_Xt
Definition ccsds124.h:580
bitvector_t work_inverted
Definition ccsds124.h:581
bitvector_t mask
Definition ccsds124.h:547
bitvector_t prev_input
Definition ccsds124.h:550
bitvector_t work_diff
Definition ccsds124.h:583
bitvector_t prev_mask
Definition ccsds124.h:548
bitvector_t change_history[CCSDS124_MAX_HISTORY]
Definition ccsds124.h:551
size_t flag_history_index
Definition ccsds124.h:558
bitvector_t initial_mask
Definition ccsds124.h:541
bitvector_t build
Definition ccsds124.h:549
Compression parameters for a single packet.
Definition ccsds124.h:94
uint8_t min_robustness
Definition ccsds124.h:95
uint8_t uncompressed_flag
Definition ccsds124.h:98
uint8_t send_mask_flag
Definition ccsds124.h:97
uint8_t new_mask_flag
Definition ccsds124.h:96