UdonLibrary
1.0.0
機械システム研究部 C++ ライブラリ
Toggle main menu visibility
読み取り中…
検索中…
一致する文字列を見つけられません
BitPack.hpp
[詳解]
1
#pragma once
2
3
#include <
Udon/Stl/EnableSTL.hpp
>
4
#include <type_traits>
5
#include <iterator>
6
#include <vector>
7
8
#include "
Bit.hpp
"
9
#include "
Math.hpp
"
10
11
namespace
Udon
12
{
13
22
template
<
typename
InputIterator,
typename
Functor>
23
void
BitPack
(
const
InputIterator begin,
const
InputIterator end, Functor callback)
24
{
25
static_assert
(std::is_same<typename std::iterator_traits<InputIterator>::value_type, uint8_t>::value,
"container element type must be uint8_t"
);
26
static_assert
(std::is_same<
typename
std::result_of<Functor(uint8_t)>::type,
void
>::value,
"callback function must be void(uint8_t)"
);
27
28
uint8_t extracteMsb = 0;
// 各要素のMSB(最上位ビット)から抽出された分のデータ
29
uint8_t extracteCount = 0;
// extracteMsbに格納されたデータのビット数
30
31
bool
isFirst =
true
;
32
33
for
(
auto
it = begin; it != end; ++it)
34
{
35
BitWrite
(extracteMsb, extracteCount,
BitRead
(*it, 7));
// MSBを抽出してextracteMsbに格納する
36
37
if
(isFirst)
38
{
39
callback(*it | 0b10000000);
// 先頭のデータはMSBが1
40
}
41
else
42
{
43
isFirst =
false
;
44
callback(*it & 0b01111111);
// MSBを除いたデータをコールバック関数に渡す
45
}
46
47
if
(++extracteCount >= 7)
48
{
49
extracteCount = 0;
50
callback(extracteMsb);
51
extracteMsb = {};
52
}
53
}
54
55
if
(extracteCount)
// extracteMsbにデータが残っていれば追加で渡す
56
{
57
callback(extracteMsb);
58
}
59
}
60
69
template
<
typename
OutputIterator,
typename
Functor>
70
bool
BitUnpack
(OutputIterator begin, OutputIterator end, Functor callback)
71
{
72
static_assert
(std::is_same<typename std::iterator_traits<OutputIterator>::value_type, uint8_t>::value,
"container element type must be uint8_t"
);
73
static_assert
(std::is_same<
typename
std::result_of<Functor()>::type, uint8_t>::value,
"callback function must be uint8_t()"
);
74
75
uint8_t extracteCount = 0;
// 通常MSBなしデータの取得数
76
77
bool
isFirst =
true
;
78
79
for
(
auto
it = begin; it != end;)
80
{
81
const
auto
data = callback();
82
83
// バイト列の先頭のMSBは必ず 1
84
if
(isFirst && not(data & 0b10000000))
85
{
86
return
false
;
87
}
88
else
89
{
90
isFirst =
false
;
91
}
92
93
*it = data;
94
++it;
95
++extracteCount;
96
97
if
(extracteCount == 7)
// 7バイトごとにMSBの集合が来る
98
{
99
extracteCount = 0;
100
101
const
uint8_t msb = callback();
102
103
auto
c = it;
104
105
for
(
int
i = 0; i < 7; ++i)
106
{
107
--c;
// c は最初、MSBの集合を指しているので、先に1バイト戻す
108
BitWrite
(*c, 7,
BitRead
(msb, 7 - 1
/*MSB bit*/
- i));
// 各要素のMSBを復元
109
}
110
}
111
}
112
113
if
(extracteCount)
// パック時 extracteMsb にデータが残っている場合、追加でデータが渡されるのでそれを処理する
114
{
115
const
uint8_t msb = callback();
116
117
auto
c = end;
118
119
for
(
int
i = 0; i < extracteCount; ++i)
120
{
121
--c;
// end は領域を持たないので、先に1バイト戻す
122
BitWrite
(*(c), 7,
BitRead
(msb, extracteCount - 1
/*MSB bit*/
- i));
// 各要素の要素のMSBを復元
123
}
124
}
125
126
return
true
;
127
}
128
132
inline
constexpr
size_t
BitPackedSize
(
size_t
size)
133
{
134
return
(
size_t
)
Udon::Ceil
(size * 8 / 7.0);
// 切り上げ
135
}
136
140
inline
constexpr
size_t
BitUnpackedSize
(
size_t
size)
141
{
142
return
size * 7 / 8;
// 切り捨て
143
}
144
148
inline
std::vector<uint8_t>
BitPack
(
const
std::vector<uint8_t>& data)
149
{
150
std::vector<uint8_t> result(
BitPackedSize
(data.size()));
151
152
auto
it = result.begin();
153
154
BitPack
(data.begin(), data.end(), [&it](uint8_t data)
155
{ *it++ = data; });
156
157
return
result;
158
}
159
160
inline
std::vector<uint8_t>
BitUnpack
(
const
std::vector<uint8_t>& data)
161
{
162
std::vector<uint8_t> result(
BitUnpackedSize
(data.size()));
163
164
auto
it = data.begin();
165
166
BitUnpack
(result.begin(), result.end(), [&it]() -> uint8_t
167
{ return *it++; });
168
169
return
result;
170
}
171
172
}
// namespace Udon
Bit.hpp
EnableSTL.hpp
Math.hpp
Udon
Definition
Bit.hpp:12
Udon::BitWrite
void BitWrite(Ty &rhs, uint8_t bit, bool value)
特定のビットに値を書き込む
Definition
Bit.hpp:61
Udon::BitPack
void BitPack(const InputIterator begin, const InputIterator end, Functor callback)
バイト列のMSB(最上位ビット)を抽出し、7bitごとに分割してコールバック関数に渡す
Definition
BitPack.hpp:23
Udon::BitUnpack
bool BitUnpack(OutputIterator begin, OutputIterator end, Functor callback)
7bit分割されたデータを結合する
Definition
BitPack.hpp:70
Udon::BitPackedSize
constexpr size_t BitPackedSize(size_t size)
ビットパックされたデータのサイズを取得する
Definition
BitPack.hpp:132
Udon::BitUnpackedSize
constexpr size_t BitUnpackedSize(size_t size)
ビットアンパックされたデータのサイズを取得する
Definition
BitPack.hpp:140
Udon::Ceil
constexpr int Ceil(double x)
小数点切り上げ (std::ceil)
Definition
Math.hpp:141
Udon::BitRead
bool BitRead(const Ty &rhs, uint8_t bit)
特定のビットを読み取る
Definition
Bit.hpp:20