Skip to content

Instantly share code, notes, and snippets.

@martincohen
Created July 15, 2020 09:42
Show Gist options
  • Save martincohen/531d61536af21bac1308a9edbd386b5d to your computer and use it in GitHub Desktop.
Save martincohen/531d61536af21bac1308a9edbd386b5d to your computer and use it in GitHub Desktop.
local function read_uint16_le(bytes, offset)
local a, b = bytes:byte(offset + 1, offset + 2)
return a + b * 0x100
end
local function read_uint16_be(bytes, offset)
local a, b = bytes:byte(offset + 1, offset + 2)
return a * 0x100 + b
end
local function read_uint32_le(bytes, offset)
local a, b, c, d = bytes:byte(offset + 1, offset + 4)
return a + b * 0x100 + c * 0x10000 + d * 0x1000000
end
local function read_uint32_be(bytes, offset)
local a, b, c, d = bytes:byte(offset + 1, offset + 4)
return a * 0x1000000 + b * 0x10000 + c * 0x100 + d
end
local detectors = {}
function detectors.png(header)
if header:sub(2, 4) ~= "PNG" then
error("not a png file")
end
if header:sub(13, 16) ~= "IHDR" then
error("IHDR not found")
end
local w = read_uint32_be(header, 0x10)
local h = read_uint32_be(header, 0x14)
return { w, h }
end
function detectors.gif(header)
if header:sub(1, 3) ~= "GIF" then
error("not a gif file")
end
local w = read_uint16_le(header, 6)
local h = read_uint16_le(header, 8)
return { w, h }
end
function detectors.psd(header)
if header:sub(1, 4) ~= '8BPS' then
error("not a psd file")
end
local w = read_uint32_be(header, 18)
local h = read_uint32_be(header, 14)
return { w, h }
end
local function get_size(path)
local extension = path:match('%.[a-zA-Z0-9]+$'):sub(2):lower()
local detector = rawget(detectors, extension)
if not detector then
error(string.format("unknown extension '%s'", extension))
end
local f = io.open(path, "rb")
local header = f:read(64)
f:close()
return detector(header)
end
return get_size
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment