CCSDS 124.0-B-1 C++ 1.0.0
CCSDS 124.0-B-1 Lossless Compression
Loading...
Searching...
No Matches
ccsds124.hpp
Go to the documentation of this file.
1
25#ifndef CCSDS124_HPP
26#define CCSDS124_HPP
27
28#include <cstring>
29
30#include "bitbuffer.hpp"
31#include "bitreader.hpp"
32#include "bitvector.hpp"
33#include "compressor.hpp"
34#include "config.hpp"
35#include "decompressor.hpp"
36#include "error.hpp"
37
38namespace ccsds124 {
39
58template <std::size_t N>
59Error compress(const std::uint8_t* input_data, std::size_t input_size, std::uint8_t* output_buffer,
60 std::size_t output_buffer_size, std::size_t& output_size,
61 std::uint8_t robustness = 0, int pt_limit = 0, int ft_limit = 0,
62 int rt_limit = 0) noexcept {
63 // Calculate packet size in bytes
64 constexpr std::size_t packet_bytes = (N + 7) / 8;
65
66 // Verify input is multiple of packet size
67 if (input_size == 0 || (input_size % packet_bytes) != 0) {
68 return Error::InvalidArg;
69 }
70
71 // Calculate number of packets
72 std::size_t num_packets = input_size / packet_bytes;
73
74 // Initialize compressor
75 Compressor<N> comp(robustness, pt_limit, ft_limit, rt_limit);
76
77 // Track output position
78 std::size_t total_output = 0;
79
80 // Countdown counters for automatic parameter management
81 int pt_counter = pt_limit;
82 int ft_counter = ft_limit;
83 int rt_counter = rt_limit;
84
85 // Process each packet
86 for (std::size_t i = 0; i < num_packets; ++i) {
87 // Load packet data
88 BitVector<N> input_vec;
89 input_vec.from_bytes(&input_data[i * packet_bytes], packet_bytes);
90
91 // Compute parameters
92 CompressParams params;
93 params.min_robustness = robustness;
94
95 if (pt_limit > 0 && ft_limit > 0 && rt_limit > 0) {
96 if (i == 0) {
97 // First packet: fixed init values
98 params.send_mask_flag = true;
99 params.uncompressed_flag = true;
100 params.new_mask_flag = false;
101 } else {
102 // ft counter
103 if (ft_counter == 1) {
104 params.send_mask_flag = true;
105 ft_counter = ft_limit;
106 } else {
107 --ft_counter;
108 params.send_mask_flag = false;
109 }
110
111 // pt counter
112 if (pt_counter == 1) {
113 params.new_mask_flag = true;
114 pt_counter = pt_limit;
115 } else {
116 --pt_counter;
117 params.new_mask_flag = false;
118 }
119
120 // rt counter
121 if (rt_counter == 1) {
122 params.uncompressed_flag = true;
123 rt_counter = rt_limit;
124 } else {
125 --rt_counter;
126 params.uncompressed_flag = false;
127 }
128
129 // Override for init packets (CCSDS requirement)
130 if (i <= static_cast<std::size_t>(robustness)) {
131 params.send_mask_flag = true;
132 params.uncompressed_flag = true;
133 params.new_mask_flag = false;
134 }
135 }
136 } else {
137 // Manual control: defaults
138 params.send_mask_flag = false;
139 params.uncompressed_flag = false;
140 params.new_mask_flag = false;
141 }
142
143 // Compress packet
144 BitBuffer<N * 6> packet_output;
145 auto result = comp.compress_packet(input_vec, packet_output, &params);
146 if (result != Error::Ok) {
147 return result;
148 }
149
150 // Convert to bytes with padding
151 std::uint8_t packet_bytes_out[N * 6 / 8 + 1];
152 std::size_t packet_size =
153 packet_output.to_bytes(packet_bytes_out, sizeof(packet_bytes_out));
154
155 // Check buffer space
156 if (total_output + packet_size > output_buffer_size) {
157 return Error::Overflow;
158 }
159
160 // Copy to output
161 std::memcpy(&output_buffer[total_output], packet_bytes_out, packet_size);
162 total_output += packet_size;
163 }
164
165 output_size = total_output;
166 return Error::Ok;
167}
168
183template <std::size_t N>
184Error decompress(const std::uint8_t* input_data, std::size_t input_size,
185 std::uint8_t* output_buffer, std::size_t output_buffer_size,
186 std::size_t& output_size, std::uint8_t robustness = 0) noexcept {
187 // Calculate packet size in bytes
188 constexpr std::size_t packet_bytes = (N + 7) / 8;
189
190 // Initialize decompressor
191 Decompressor<N> decomp(robustness);
192
193 // Initialize bit reader
194 BitReader reader(input_data, input_size * 8);
195
196 // Track output position
197 std::size_t total_output = 0;
198
199 // Decompress packets until input exhausted
200 while (reader.remaining() > 0) {
201 BitVector<N> output;
202 auto result = decomp.decompress_packet(reader, output);
203 if (result != Error::Ok) {
204 return result;
205 }
206
207 // Check output buffer space
208 if (total_output + packet_bytes > output_buffer_size) {
209 return Error::Overflow;
210 }
211
212 // Copy to output buffer
213 output.to_bytes(&output_buffer[total_output], packet_bytes);
214 total_output += packet_bytes;
215
216 // Align to byte boundary for next packet
217 reader.align_byte();
218 }
219
220 output_size = total_output;
221 return Error::Ok;
222}
223
228inline const char* version() noexcept {
229 return "1.0.0";
230}
231
232} // namespace ccsds124
233
234#endif // CCSDS124_HPP
Variable-length bit buffer for building compressed output.
Sequential bit reading from compressed data.
Fixed-length bit vector with static allocation.
Variable-length bit buffer with static allocation.
Definition bitbuffer.hpp:51
std::size_t to_bytes(std::uint8_t *bytes, std::size_t max_bytes) const noexcept
Convert bit buffer to byte array.
Sequential bit reader for compressed data.
Definition bitreader.hpp:38
void align_byte() noexcept
Skip to next byte boundary.
std::size_t remaining() const noexcept
Get remaining bits.
Fixed-length bit vector with compile-time size.
Definition bitvector.hpp:90
void from_bytes(const std::uint8_t *bytes, std::size_t num_bytes) noexcept
Load from byte array (big-endian).
void to_bytes(std::uint8_t *bytes, std::size_t num_bytes) const noexcept
Store to byte array (big-endian).
CCSDS 124.0-B-1 compressor with static memory allocation.
Error compress_packet(const BitVector< N > &input, BitBuffer< OutputSize > &output, const CompressParams *params=nullptr) noexcept
Compress a single input packet.
CCSDS 124.0-B-1 decompressor with static memory allocation.
Error decompress_packet(BitReader &reader, BitVector< N > &output) noexcept
Decompress a single compressed packet.
CCSDS 124.0-B-1 compression algorithm implementation.
CCSDS 124.0-B-1 compile-time configuration.
CCSDS 124.0-B-1 decompression algorithm implementation.
CCSDS 124.0-B-1 error handling.
const char * version() noexcept
Get library version.
Definition ccsds124.hpp:228
Error
Error codes for error-code-based error handling.
Definition error.hpp:29
@ Overflow
Buffer overflow.
@ InvalidArg
Invalid argument.
Error decompress(const std::uint8_t *input_data, std::size_t input_size, std::uint8_t *output_buffer, std::size_t output_buffer_size, std::size_t &output_size, std::uint8_t robustness=0) noexcept
Decompress multi-packet data stream.
Definition ccsds124.hpp:184
Error compress(const std::uint8_t *input_data, std::size_t input_size, std::uint8_t *output_buffer, std::size_t output_buffer_size, std::size_t &output_size, std::uint8_t robustness=0, int pt_limit=0, int ft_limit=0, int rt_limit=0) noexcept
Compress multi-packet data stream.
Definition ccsds124.hpp:59
Compression parameters for a single packet.
bool new_mask_flag
p_t: Update mask from build vector
bool uncompressed_flag
r_t: Send uncompressed
bool send_mask_flag
f_t: Include mask in output
std::uint8_t min_robustness
R_t: Minimum robustness level (0-7)