figura-tools/lua/decode.lua

89 lines
2.2 KiB
Lua

local function getUint16(bytes, idx)
return bytes[idx] * 256 + bytes[idx + 1]
end
local function getUint8(bytes, idx)
return bytes[idx]
end
local function componentToHex(c)
return string.format("%02x", c)
end
local function rgbToHex(r, g, b)
return "#" .. componentToHex(r) .. componentToHex(g) .. componentToHex(b)
end
local function unpack_block(whole_buffer, startByte)
local paletteIdx = getUint16(whole_buffer, startByte)
local packedInfo = getUint8(whole_buffer, startByte + 2)
local blockAmount = math.floor(packedInfo / 16)
local byteRemoval = packedInfo % 16
local textArr = {}
for i = 1, blockAmount do
local byte = getUint8(whole_buffer, startByte + 2 + i)
for bit = 7, 0, -1 do
table.insert(textArr, ((math.floor(byte / (2 ^ bit)) % 2) == 1) and "\n" or "")
end
end
if byteRemoval > 0 then
for i = 1, byteRemoval do
table.remove(textArr)
end
end
local endByte = startByte + 2 + blockAmount
return { paletteIdx = paletteIdx, text = table.concat(textArr), endByte = endByte }
end
local function unpack_blocks(packed)
local size = getUint16(packed, 1)
local palette = {}
local idx = 3
for i = 1, 300 do
table.insert(palette, {
getUint8(packed, idx + 1),
getUint8(packed, idx + 2),
getUint8(packed, idx + 3)
})
idx = idx + 3
end
local blocks_unpacked = {}
idx = idx + 1
while idx <= #packed do
local block = unpack_block(packed, idx)
idx = block.endByte + 1
block.color = rgbToHex(table.unpack(palette[block.paletteIdx + 1]))
block.paletteIdx = nil
block.endByte = nil
table.insert(blocks_unpacked, block)
end
return blocks_unpacked
end
return { unpack_blocks = unpack_blocks }
--[[
local base64 = require("base64")
local lz4 = require("lz4")
local bytes = base64.decode(image)
local byte_table = {}
for num in string.gmatch(bytes, "%d+") do
table.insert(byte_table, tonumber(num))
end
local decomp = lz4.decompress(byte_table)
local unpacked = unpack_blocks(decomp)
local json = <..json serializer..>:serialize(unpacked);
]]