エスケープシーケンスの背景色で描画してみた。
24bitカラーと8bitカラーだけ、パースも適当だけど・・・
環境はWindows10(1903) + Windows標準のコマンドプロンプト + nyagos
最初、1byteずつ読み込んでいたんだけど、どうも取りこぼしているようだったので
最初に全部読み込んでからパースしてます。
nyagos.alias.bmp = function(args)
local bmp = io.open(args[1], 'r'):read('*a')
-- Headr
local p = 1
p = p + 2 -- BM
p = p + 4 -- File Size
p = p + 2 -- Reserved
p = p + 2 -- Reserved
local offset = bmp:byte(p, p + 1)
p = p+ 1
offset = offset + bmp:byte(p, p + 1) * 0x100
p = p + 1
offset = offset + bmp:byte(p, p + 1) * 0x10000
p = p + 1
offset = offset + bmp:byte(p, p + 1) * 0x1000000
p = p + 1
p = p + 4 -- Info Header Size
local width = bmp:byte(p, p + 1)
p = p + 1
width = width + bmp:byte(p, p + 1) * 0x100
p = p + 1
width = width + bmp:byte(p, p + 1) * 0x10000
p = p + 1
width = width + bmp:byte(p, p + 1) * 0x1000000
p = p + 1
local height = bmp:byte(p, p + 1)
p = p + 1
height = height + bmp:byte(p, p + 1) * 0x100
p = p + 1
height = height + bmp:byte(p, p + 1) * 0x10000
p = p + 1
height = height + bmp:byte(p, p + 1) * 0x1000000
p = p + 1
p = p + 2 -- Plane. always 1
local bits = bmp:byte(p, p + 1)
p = p + 1
bits = bits + bmp:byte(p, p + 1) * 0x100
p = p + 1
local is24bit = false
local is8bit = false
if bits == 24 then
is24bit = true
elseif bits == 8 then
is8bit = true
else
print("Unsupported format")
return
end
p = p + 4 -- Compress
p = p + 4 -- Data Size
p = p + 4 -- Resolution
p = p + 4 -- Resolution
local palleteSize = bmp:byte(p, p + 1)
p = p + 1
palleteSize = palleteSize + bmp:byte(p, p + 1) * 0x100
p = p + 1
palleteSize = palleteSize + bmp:byte(p, p + 1) * 0x10000
p = p + 1
palleteSize = palleteSize + bmp:byte(p, p + 1) * 0x1000000
p = p + 1
p = p + 4 -- Important Color
local pallete = {}
for i = 1, palleteSize, 1 do
pallete[i] = {}
pallete[i][1] = bmp:byte(p, p + 1);
p = p + 1
pallete[i][2] = bmp:byte(p, p + 1);
p = p + 1
pallete[i][3] = bmp:byte(p, p + 1);
p = p + 1
pallete[i][4] = bmp:byte(p, p + 1);
p = p + 1
end
p = offset + 1
-- Data
local img = {}
for j = 1, height, 1 do
img[height-j+1] = {}
local r, g, b
for i = 1, width, 1 do
if is24bit then
b = bmp:byte(p, p + 1)
p = p + 1
g = bmp:byte(p, p + 1)
p = p + 1
r = bmp:byte(p, p + 1)
p = p + 1
elseif is8bit then
local pp = bmp:byte(p, p + 1)
p = p + 1
if pp ~= nil then
b = pallete[pp + 1][1]
g = pallete[pp + 1][2]
r = pallete[pp + 1][3]
end
end
img[height-j+1][i] = '\027[48;2;' .. r .. ';' .. g .. ';' .. b .. 'm \027[49m'
end
-- padding
if is24bit then
p = p + width % 4
elseif is8bit then
p = p + (width * 3) % 4
end
end
for _, r in pairs(img) do
for _, c in pairs(r) do
nyagos.write(c)
end
nyagos.write('\n')
end
end