mime types
[software/python-on-guile.git] / modules / language / python / module / imghdr.py
1 module(imghdr)
2
3 """Recognize image file formats based on their first few bytes."""
4
5 from os import PathLike
6
7 __all__ = ["what"]
8
9 #-------------------------#
10 # Recognize image headers #
11 #-------------------------#
12
13 def what(file, h=None):
14 f = None
15 try:
16 if h is None:
17 if isinstance(file, (str, PathLike)):
18 f = open(file, 'rb')
19 h = f.read(32)
20 else:
21 location = file.tell()
22 h = file.read(32)
23 file.seek(location)
24 for tf in tests:
25 res = tf(h, f)
26 if res:
27 return res
28 finally:
29 if f: f.close()
30 return None
31
32
33 #---------------------------------#
34 # Subroutines per image file type #
35 #---------------------------------#
36
37 tests = []
38
39 def test_jpeg(h, f):
40 """JPEG data in JFIF or Exif format"""
41 if h[6:10] in (b'JFIF', b'Exif'):
42 return 'jpeg'
43
44 tests.append(test_jpeg)
45
46 def test_png(h, f):
47 if h.startswith(b'\211PNG\r\n\032\n'):
48 return 'png'
49
50 tests.append(test_png)
51
52 def test_gif(h, f):
53 """GIF ('87 and '89 variants)"""
54 if h[:6] in (b'GIF87a', b'GIF89a'):
55 return 'gif'
56
57 tests.append(test_gif)
58
59 def test_tiff(h, f):
60 """TIFF (can be in Motorola or Intel byte order)"""
61 if h[:2] in (b'MM', b'II'):
62 return 'tiff'
63
64 tests.append(test_tiff)
65
66 def test_rgb(h, f):
67 """SGI image library"""
68 if h.startswith(b'\001\332'):
69 return 'rgb'
70
71 tests.append(test_rgb)
72
73 def test_pbm(h, f):
74 """PBM (portable bitmap)"""
75 if len(h) >= 3 and \
76 h[0] == ord(b'P') and h[1] in b'14' and h[2] in b' \t\n\r':
77 return 'pbm'
78
79 tests.append(test_pbm)
80
81 def test_pgm(h, f):
82 """PGM (portable graymap)"""
83 if len(h) >= 3 and \
84 h[0] == ord(b'P') and h[1] in b'25' and h[2] in b' \t\n\r':
85 return 'pgm'
86
87 tests.append(test_pgm)
88
89 def test_ppm(h, f):
90 """PPM (portable pixmap)"""
91 if len(h) >= 3 and \
92 h[0] == ord(b'P') and h[1] in b'36' and h[2] in b' \t\n\r':
93 return 'ppm'
94
95 tests.append(test_ppm)
96
97 def test_rast(h, f):
98 """Sun raster file"""
99 if h.startswith(b'\x59\xA6\x6A\x95'):
100 return 'rast'
101
102 tests.append(test_rast)
103
104 def test_xbm(h, f):
105 """X bitmap (X10 or X11)"""
106 if h.startswith(b'#define '):
107 return 'xbm'
108
109 tests.append(test_xbm)
110
111 def test_bmp(h, f):
112 if h.startswith(b'BM'):
113 return 'bmp'
114
115 tests.append(test_bmp)
116
117 def test_webp(h, f):
118 if h.startswith(b'RIFF') and h[8:12] == b'WEBP':
119 return 'webp'
120
121 tests.append(test_webp)
122
123 def test_exr(h, f):
124 if h.startswith(b'\x76\x2f\x31\x01'):
125 return 'exr'
126
127 tests.append(test_exr)
128
129 #--------------------#
130 # Small test program #
131 #--------------------#
132
133 def test():
134 import sys
135 recursive = 0
136 if sys.argv[1:] and sys.argv[1] == '-r':
137 del sys.argv[1:2]
138 recursive = 1
139 try:
140 if sys.argv[1:]:
141 testall(sys.argv[1:], recursive, 1)
142 else:
143 testall(['.'], recursive, 1)
144 except KeyboardInterrupt:
145 sys.stderr.write('\n[Interrupted]\n')
146 sys.exit(1)
147
148 def testall(list, recursive, toplevel):
149 import sys
150 import os
151 for filename in list:
152 if os.path.isdir(filename):
153 print(filename + '/:', end=' ')
154 if recursive or toplevel:
155 print('recursing down:')
156 import glob
157 names = glob.glob(os.path.join(filename, '*'))
158 testall(names, recursive, 0)
159 else:
160 print('*** directory (use -r) ***')
161 else:
162 print(filename + ':', end=' ')
163 sys.stdout.flush()
164 try:
165 print(what(filename))
166 except OSError:
167 print('*** not found ***')
168
169 if __name__ == '__main__':
170 test()