CCSDS 124.0-B-1 C++ 1.0.0
CCSDS 124.0-B-1 Lossless Compression
Loading...
Searching...
No Matches
bitreader.hpp
Go to the documentation of this file.
1
25#ifndef CCSDS124_BITREADER_HPP
26#define CCSDS124_BITREADER_HPP
27
28#include "config.hpp"
29
30namespace ccsds124 {
31
38class BitReader {
39public:
46 BitReader(const std::uint8_t* data, std::size_t num_bits) noexcept
47 : data_(data), num_bits_(num_bits), bit_pos_(0) {}
48
54 inline int read_bit() noexcept {
55 if (bit_pos_ >= num_bits_) [[unlikely]] {
56 return -1;
57 }
58
59 std::size_t byte_idx = bit_pos_ >> 3; // bit_pos_ / 8
60 std::size_t bit_idx = bit_pos_ & 7; // bit_pos_ % 8
61
62 // MSB-first: bit 0 of byte is at position 7
63 int bit = (data_[byte_idx] >> (7 - bit_idx)) & 1;
64 ++bit_pos_;
65
66 return bit;
67 }
68
78 std::uint32_t read_bits(std::size_t num_bits) noexcept {
79 if (num_bits == 0 || num_bits > 32) [[unlikely]] {
80 return 0;
81 }
82
83 if (bit_pos_ + num_bits > num_bits_) [[unlikely]] {
84 return 0; // Underflow protection
85 }
86
87 // Fast path: byte-aligned reads (common case)
88 if ((bit_pos_ & 7) == 0 && (num_bits & 7) == 0) [[likely]] {
89 std::size_t byte_idx = bit_pos_ >> 3;
90 std::size_t num_bytes = num_bits >> 3;
91 std::uint32_t value = 0;
92 for (std::size_t i = 0; i < num_bytes; ++i) {
93 value = (value << 8) | data_[byte_idx + i];
94 }
95 bit_pos_ += num_bits;
96 return value;
97 }
98
99 // General case: unaligned reads
100 std::uint32_t value = 0;
101 std::size_t remaining = num_bits;
102
103 while (remaining > 0) {
104 std::size_t byte_idx = bit_pos_ >> 3;
105 std::size_t bit_idx = bit_pos_ & 7;
106
107 // Bits available in current byte
108 std::size_t bits_in_byte = 8 - bit_idx;
109 std::size_t bits_to_read = (remaining < bits_in_byte) ? remaining : bits_in_byte;
110
111 // Extract bits from current byte (MSB-first)
112 std::uint8_t byte_val = data_[byte_idx];
113 std::uint32_t shift = 8 - bit_idx - bits_to_read;
114 std::uint32_t mask = (1U << bits_to_read) - 1U;
115 std::uint32_t extracted = (byte_val >> shift) & mask;
116
117 value = (value << bits_to_read) | extracted;
118 bit_pos_ += bits_to_read;
119 remaining -= bits_to_read;
120 }
121
122 return value;
123 }
124
130 [[nodiscard]] std::size_t position() const noexcept {
131 return bit_pos_;
132 }
133
139 [[nodiscard]] std::size_t remaining() const noexcept {
140 return (bit_pos_ < num_bits_) ? (num_bits_ - bit_pos_) : 0;
141 }
142
148 void align_byte() noexcept {
149 std::size_t bit_offset = bit_pos_ & 7; // bit_pos_ % 8
150 if (bit_offset != 0) {
151 bit_pos_ += (8 - bit_offset);
152 }
153 }
154
155private:
156 const std::uint8_t* data_;
157 std::size_t num_bits_;
158 std::size_t bit_pos_;
159};
160
161} // namespace ccsds124
162
163#endif // CCSDS124_BITREADER_HPP
Sequential bit reader for compressed data.
Definition bitreader.hpp:38
std::uint32_t read_bits(std::size_t num_bits) noexcept
Read multiple bits as unsigned value.
Definition bitreader.hpp:78
BitReader(const std::uint8_t *data, std::size_t num_bits) noexcept
Construct a bit reader.
Definition bitreader.hpp:46
void align_byte() noexcept
Skip to next byte boundary.
std::size_t position() const noexcept
Get current bit position.
std::size_t remaining() const noexcept
Get remaining bits.
int read_bit() noexcept
Read a single bit.
Definition bitreader.hpp:54
CCSDS 124.0-B-1 compile-time configuration.