71 lines
1.9 KiB
Lua
71 lines
1.9 KiB
Lua
local function BitWriter() return {
|
|
accumulator = 0, -- For current byte.
|
|
bitCount = 0, -- Bits set in current byte.
|
|
outChars = {},
|
|
|
|
-- writer:writeBit( bit )
|
|
writeBit = function(writer, bit)
|
|
writer.bitCount = writer.bitCount + 1
|
|
if bit > 0 then
|
|
writer.accumulator = writer.accumulator + 2^(8-writer.bitCount)
|
|
end
|
|
if writer.bitCount == 8 then
|
|
writer:_flush()
|
|
end
|
|
end,
|
|
|
|
-- writer:writeLsb( value, width )
|
|
writeLsb = function(writer, value, width)
|
|
for i = 1, width do
|
|
writer:writeBit(value%2)
|
|
value = math.floor(value/2)
|
|
end
|
|
end,
|
|
|
|
-- dataString = writer:getOutput( )
|
|
getOutput = function(writer)
|
|
writer:_flush()
|
|
return table.concat(writer.outChars)
|
|
end,
|
|
|
|
_flush = function(writer)
|
|
if writer.bitCount == 0 then return end
|
|
|
|
table.insert(writer.outChars, string.char(writer.accumulator))
|
|
writer.accumulator = 0
|
|
writer.bitCount = 0
|
|
end,
|
|
} end
|
|
|
|
local function BitReader(data) return {
|
|
bitPosition = 0, -- Absolute position in 'data'.
|
|
|
|
-- bit = reader:readBit( ) -- Returns nil at end-of-data.
|
|
readBit = function(reader)
|
|
reader.bitPosition = reader.bitPosition + 1
|
|
local bytePosition = math.floor((reader.bitPosition-1)/8) + 1
|
|
|
|
local byte = data:byte(bytePosition)
|
|
if not byte then return nil end
|
|
|
|
local bitIndex = ((reader.bitPosition-1)%8) + 1
|
|
return math.floor(byte / 2^(8-bitIndex)) % 2
|
|
end,
|
|
|
|
-- value = reader:readLsb( width ) -- Returns nil at end-of-data.
|
|
readLsb = function(reader, width)
|
|
local accumulator = 0
|
|
|
|
for i = 1, width do
|
|
local bit = reader:readBit()
|
|
if not bit then return nil end
|
|
|
|
if bit > 0 then
|
|
accumulator = accumulator + 2^(i-1)
|
|
end
|
|
end
|
|
|
|
return accumulator
|
|
end,
|
|
} end
|