-
Notifications
You must be signed in to change notification settings - Fork 24
/
jpegwdx.lua
150 lines (142 loc) · 4.08 KB
/
jpegwdx.lua
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
-- jpeginfowdx.lua (cross-platform)
-- 2021.04.02
--[[
Returns some info from JPEG.
See list of supported fields in table "fields".
"JPEG compression" field will return text, other fields are boolean (true if marker exists).
ITU T.81/IEC 10918-1 JPEG (1994)
ITU T.84/IEC 10918-3 JPEG extensions (1997)
ITU T.87/IEC 14495-1 JPEG LS
]]
local fields = {
{"JFIF", "", 6},
{"JFXX", "", 6},
{"EXIF", "", 6},
{"XMP", "", 6},
{"ICC color profile", "", 6},
{"Adobe Photoshop IRB, IPTC", "", 6},
{"Adobe segment", "", 6},
{"Comment", "", 6},
{"JPEG compression", "", 8}
}
local compres = {
{"SOF0", 0xc0, "Baseline DCT"},
{"SOF1", 0xc1, "Extended sequential DCT"},
{"SOF2", 0xc2, "Progressive DCT"},
{"SOF3", 0xc3, "Lossless (sequential)"},
{"SOF5", 0xc5, "Differential sequential DCT"},
{"SOF6", 0xc6, "Differential progressive DCT"},
{"SOF7", 0xc7, "Differential lossless (sequential)"},
{"SOF9", 0xc9, "Extended sequential DCT, arithmetic coding"},
{"SOF10", 0xca, "Progressive DCT, arithmetic coding"},
{"SOF11", 0xcb, "Lossless (sequential), arithmetic coding"},
{"SOF13", 0xcd, "Differential sequential DCT, arithmetic coding"},
{"SOF14", 0xce, "Differential progressive DCT, arithmetic coding"},
{"SOF15", 0xcf, "Differential lossless (sequential), arithmetic coding"},
{"SOF48", 0xf7, "JPEG-LS baseline"},
{"LSE", 0xf8, "JPEG-LS baseline"},
{"SOF57", 0xf9, "JPEG LS extensions"}
}
function ContentGetSupportedField(FieldIndex)
if fields[FieldIndex + 1] ~= nil then
return fields[FieldIndex + 1][1], fields[FieldIndex + 1][2], fields[FieldIndex + 1][3]
end
return "", "", 0
end
function ContentGetDefaultSortOrder(FieldIndex)
return 1; --or -1
end
function ContentGetDetectString()
return 'EXT="*"'
end
function ContentGetValue(FileName, FieldIndex, UnitIndex, flags)
if FieldIndex >= #fields then return nil end
local at = SysUtils.FileGetAttr(FileName)
if (at < 0) or (math.floor(at / 0x00000010) % 2 ~= 0) then return nil end
local ar = {
false,
false,
false,
false,
false,
false,
false,
false,
nil
}
local d, n, t
local p = 0
local h = io.open(FileName, 'rb')
if h == nil then return nil end
local d = h:read(2)
-- magic: ff d8
if (d == nil) or (BinToNumBE(d, 1, 2) ~= 65496) then
h:close()
return nil
end
while true do
d = h:read(4)
if string.byte(d, 1) ~= 0xff then break end
p = h:seek()
n = string.byte(d, 2)
-- DRI, 0xffdd
if n == 0xdd then
p = p + 2
-- RSTn, 0xffd0 - 0xffd7
elseif (n > 207) and (n < 216) then
p = p - 2
else
p = p + BinToNumBE(d, 3, 4) - 2
d = h:read(29)
if n == 0xe0 then
if string.byte(d, 5) == 0x00 then
t = string.sub(d, 1, 4)
if t == 'JFIF' then
ar[1] = true
elseif t == 'JFXX' then
ar[2] = true
end
end
elseif n == 0xe1 then
if string.byte(d, 5) == 0x00 then
if string.sub(d, 1, 4) == 'Exif' then ar[3] = true end
else
if string.byte(d, 29) == 0x00 then
if string.sub(d, 1, 28) == 'http://ns.adobe.com/xap/1.0/' then ar[4] = true end
end
end
elseif n == 0xe2 then
if string.byte(d, 12) == 0x00 then
if string.sub(d, 1, 11) == 'ICC_PROFILE' then ar[5] = true end
end
elseif n == 0xed then
if string.byte(d, 14) == 0x00 then
if string.sub(d, 1, 13) == 'Photoshop 3.0' then ar[6] = true end
end
elseif n == 0xee then
if string.byte(d, 6) == 0x00 then
if string.sub(d, 1, 5) == 'Adobe' then ar[7] = true end
end
elseif n == 0xfe then
ar[86] = true
else
for i = 1, #compres do
if n == compres[i][2] then
ar[9] = compres[i][3]
break
end
end
end
end
h:seek('set', p)
end
h:close()
return ar[FieldIndex + 1]
end
function BinToNumBE(d, n1, n2)
local r = ''
for i = n1, n2 do
r = r .. string.format('%02x', string.byte(d, i))
end
return tonumber('0x' .. r)
end