-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbitstream.cpp
More file actions
86 lines (70 loc) · 2.19 KB
/
bitstream.cpp
File metadata and controls
86 lines (70 loc) · 2.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "bitstream.h"
#include <stdexcept>
void BitWriter::writeBits(uint32_t value, int bitCount) {
if (bitCount <= 0 || bitCount > 32) {
throw std::invalid_argument("Bit count must be between 1 and 32");
}
for (int i = bitCount - 1; i >= 0; --i) {
const uint8_t bit = static_cast<uint8_t>((value >> i) & 1U);
currentByte_ = static_cast<uint8_t>((currentByte_ << 1) | bit);
++bitsInCurrentByte_;
++writtenBits_;
if (bitsInCurrentByte_ == 8) {
data_.push_back(currentByte_);
currentByte_ = 0;
bitsInCurrentByte_ = 0;
}
}
}
void BitWriter::writeBit(bool bit) {
writeBits(bit ? 1U : 0U, 1);
}
void BitWriter::alignToByte() {
if (bitsInCurrentByte_ == 0) {
return;
}
const int padBits = 8 - bitsInCurrentByte_;
currentByte_ = static_cast<uint8_t>(currentByte_ << padBits);
data_.push_back(currentByte_);
currentByte_ = 0;
bitsInCurrentByte_ = 0;
}
std::size_t BitWriter::bitCount() const {
return writtenBits_;
}
std::vector<uint8_t> BitWriter::takeBytes() {
alignToByte();
return std::move(data_);
}
BitReader::BitReader(const std::vector<uint8_t> &data) : data_(data) {}
bool BitReader::readBits(int bitCount, uint32_t &outValue) {
if (!ok_ || bitCount < 0 || bitCount > 32 || bitsRemaining() < static_cast<std::size_t>(bitCount)) {
ok_ = false;
outValue = 0;
return false;
}
outValue = 0;
for (int i = 0; i < bitCount; ++i) {
const std::size_t absoluteBit = bitOffset_ + static_cast<std::size_t>(i);
const std::size_t byteIndex = absoluteBit / 8;
const int shift = 7 - static_cast<int>(absoluteBit % 8);
const uint32_t bit = (data_[byteIndex] >> shift) & 1U;
outValue = (outValue << 1U) | bit;
}
bitOffset_ += static_cast<std::size_t>(bitCount);
return true;
}
bool BitReader::readBit(bool &outBit) {
uint32_t value = 0;
if (!readBits(1, value)) {
return false;
}
outBit = (value != 0);
return true;
}
bool BitReader::ok() const {
return ok_;
}
std::size_t BitReader::bitsRemaining() const {
return data_.size() * 8U - bitOffset_;
}