Skip to content

Instantly share code, notes, and snippets.

@blackknight36
Created September 18, 2019 21:25
Show Gist options
  • Save blackknight36/e19c3ca21e9341469b5b141bc8a34335 to your computer and use it in GitHub Desktop.
Save blackknight36/e19c3ca21e9341469b5b141bc8a34335 to your computer and use it in GitHub Desktop.
#!/usr/bin/env lua
local function BitAND(a,b)--Bitwise and
local p,c=1,0
while a>0 and b>0 do
local ra,rb=a%2,b%2
if ra+rb>1 then c=c+p end
a,b,p=(a-ra)/2,(b-rb)/2,p*2
end
return c
end
-- Offset (hex) Offset (dec) Size (bytes) Windows BITMAPINFOHEADER[1]
-- 0E 14 4 the size of this header (40 bytes)
-- 12 18 4 the bitmap width in pixels (signed integer)
-- 16 22 4 the bitmap height in pixels (signed integer)
-- 1A 26 2 the number of color planes (must be 1)
-- 1C 28 2 the number of bits per pixel, which is the color depth of the image. Typical values are 1, 4, 8, 16, 24 and 32.
-- 1E 30 4 the compression method being used. See the next table for a list of possible values
-- 22 34 4 the image size. This is the size of the raw bitmap data; a dummy 0 can be given for BI_RGB bitmaps.
-- 26 38 4 the horizontal resolution of the image. (pixel per metre, signed integer)
-- 2A 42 4 the vertical resolution of the image. (pixel per metre, signed integer)
-- 2E 46 4 the number of colors in the color palette, or 0 to default to 2n
-- 32 50 4 the number of important colors used, or 0 when every color is important; generally ignored
-- See https://en.wikipedia.org/wiki/BMP_file_format#References for more info
-- Color table starts at 0x36 - 4 bpp = 16 colors * 4 bytes each
function read_bitmap(file)
local f = assert(io.open(file, "rb"))
-- 0x0A contains the offset to the pixel data
f:seek("set", 0x0A)
offset = string.byte(f:read(4));
print("offset: " .. offset);
f:seek("set", 0x12)
width = string.byte(f:read(4));
print("width: " .. width);
f:seek("set", 0x16)
height = string.byte(f:read(4));
print("height: " .. height);
f:seek("set", 0x1c)
bpp = string.byte(f:read(1));
print("bpp: " .. bpp);
-- Read color data. Palette data starts at 0x36 and each color uses 4 bytes of data.
colors = {}
f:seek("set", 0x36)
for i = 1,16,1 do
colors[i] = string.byte(f:read(4));
f:seek("cur", 4);
end
local imagedata = {}
-- 4 bpp = 2 pixels per byte. We only need to read 32 bytes of data to represent 64 pixels.
-- 32 rows * 32 bytes = 2048 bytes = 4096 pixels (64x64)
for i=1,height do
r = {}
-- Read 32 bytes = 64 pixels
for j = 1, width/(8/bpp), 1 do
f:seek("set", offset);
p = string.byte(f:read(1));
HiNIBBLE = math.floor(p / 0x10); -- 'ASCII value divided by 16 colors
LoNIBBLE = BitAND(p, 0x0F); -- ASC AND &HF 'ASCII value AND 15
table.insert(r, HiNIBBLE);
table.insert(r, LoNIBBLE);
offset = offset +1;
end
table.insert(imagedata, r)
--offset = offset + width;
end
f:close()
return imagedata
end
img = read_bitmap(arg[1])
-- ANSI color codes
-- -- foreground
-- black = 30,
-- red = 31,
-- green = 32,
-- yellow = 33,
-- blue = 34,
-- magenta = 35,
-- cyan = 36,
-- white = 37,
-- -- background
-- onblack = 40,
-- onred = 41,
-- ongreen = 42,
-- onyellow = 43,
-- onblue = 44,
-- onmagenta = 45,
-- oncyan = 46,
-- onwhite = 47,
colors = {
[0] = 30,
[1] = 31,
[2] = 32,
[3] = 33,
[4] = 30,
[5] = 35,
[6] = 36,
[7] = 37,
[8] = 30,
[9] = 32,
[0xA] = 31,
[0xB] = 37,
[0xC] = 32,
[0xD] = 32,
[0xE] = 32,
[0xF] = 32,
}
for i = #img, 1, -1 do
value = img[i]
for key, value in pairs(value) do
c_code = colors[value];
io.write('\27[' .. c_code .. 'm' .. string.format("%02X", value) .. '\27[0m');
end
io.write("\n");
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment