1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
function GetImageWidthHeight(file)
	local fileinfo=type(file)
	if type(file)=="string" then
		file=assert(io.open(file,"rb"))
	else
		fileinfo=file:seek("cur")
	end
	local width,height=0,0
	-- Detect if PNG
	file:seek("set",1)
	if file:read(3)=="PNG" then
		file:seek("set",16)
		local widthstr,heightstr=file:read(4),file:read(4)
		if type(fileinfo)=="number" then
			file:seek("set",fileinfo)
		else
			file:close()
		end
		width=widthstr:sub(1,1):byte()*16777216+widthstr:sub(2,2):byte()*65536+widthstr:sub(3,3):byte()*256+widthstr:sub(4,4):byte()
		height=heightstr:sub(1,1):byte()*16777216+heightstr:sub(2,2):byte()*65536+heightstr:sub(3,3):byte()*256+heightstr:sub(4,4):byte()
		return width,height
	end
	file:seek("set")
	-- Detect if BMP
	if file:read(2)=="BM" then
		file:seek("set",18)
		local widthstr,heightstr=file:read(4),file:read(4)
		if type(fileinfo)=="number" then
			file:seek("set",fileinfo)
		else
			file:close()
		end
		width=widthstr:sub(4,4):byte()*16777216+widthstr:sub(3,3):byte()*65536+widthstr:sub(2,2):byte()*256+widthstr:sub(1,1):byte()
		height=heightstr:sub(4,4):byte()*16777216+heightstr:sub(3,3):byte()*65536+heightstr:sub(2,2):byte()*256+heightstr:sub(1,1):byte()
		return width,height
	end
	-- Detect if JPG/JPEG
	file:seek("set")
	if file:read(2)=="\255\216" then
		-- Search for Progressive/Baseline DCT
		local lastb,curb=0,0
		local sstr=file:read(1)
		while sstr~=nil do
			lastb=curb
			curb=sstr:byte()
			if (curb==194 or curb==192) and lastb==255 then
				file:seek("cur",3)
				local sizestr=file:read(4)
				if type(fileinfo)=="number" then
					file:seek("set",fileinfo)
				else
					file:close()
				end
				width=sizestr:sub(1,1):byte()*256+sizestr:sub(2,2):byte()
				height=sizestr:sub(3,3):byte()*256+sizestr:sub(4,4):byte()
				return width,height
			end
			sstr=file:read(1)
		end
	end
	if type(fileinfo)=="number" then
		file:seek("set",fileinfo)
	else
		file:close()
	end
	return nil
end