-
Notifications
You must be signed in to change notification settings - Fork 0
/
BitStream.m
68 lines (59 loc) · 2.25 KB
/
BitStream.m
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
classdef BitStream
% Form an array of bytes and fill it as a bitstream.
properties
size
pos
data
end
methods
function self = BitStream(size)
self.size = size;
self.pos = 0;
self.data = zeros([size 1],'uint8');
end
function self = insert(self, data, nbits, invmsb)
% Insert lowest nbits of data in OutputBuffer.
if nargin < 4, invmsb = false; end
if invmsb
data = self.invertmsb(data,nbits);
end
datainbytes = self.splitinbytes(data, nbits, bitand(self.pos,7));
ind = floor(self.pos/8);
for byte = datainbytes
if ind >= self.size
break;
end
self.data(ind+1) = bitor(self.data(ind+1),byte);
ind = ind + 1;
end
self.pos = self.pos + nbits;
end
function x = maskupperbits(~,data,nbits)
% Set all bits higher than nbits to zero.
mask = double(bitand(bitshift(uint64(4294967295),nbits),4294967295));
mask = -mask - 1; %for integers, ~x is equivalent to (-x) - 1
mask = mask + intmax('uint32') + 1;
x = bitand(data,mask);
end
function x = invertmsb(~, data, nbits)
% Invert MSB of data, data being only lowest nbits.
mask = 1*2^(nbits-1);
x = bitxor(data,mask);
end
function datainbytes = splitinbytes(self,data,nbits,pos)
% Split input data in bytes to allow insertion in buffer by OR operation.
data = self.maskupperbits(data, nbits);
shift = 8 - bitand(nbits,7) + 8 - pos;
shift = bitand(shift,7);
data = bitshift(data,shift);
nbits = nbits + shift;
datainbytes = [];
loopcount = 1 + floor((nbits-1)/8);
for i = 1:loopcount
datainbytes = [bitand(data,255) datainbytes]; %#ok<AGROW>
data = bitshift(data,-8);
end
datainbytes = uint8(datainbytes);
end
end
end