blob: 1683024cb72923d6a02bf50230ad9860aa69875c [file] [log] [blame]
Guido van Rossum54f22ed2000-02-04 15:10:34 +00001"""Recognize image file formats based on their first few bytes."""
Guido van Rossum1c34fc71992-05-27 14:06:59 +00002
Skip Montanaro17ab1232001-01-24 06:27:27 +00003__all__ = ["what"]
Guido van Rossum1c34fc71992-05-27 14:06:59 +00004
5#-------------------------#
Guido van Rossum45ac47c1997-10-08 15:22:32 +00006# Recognize image headers #
Guido van Rossum1c34fc71992-05-27 14:06:59 +00007#-------------------------#
8
Guido van Rossum45ac47c1997-10-08 15:22:32 +00009def what(file, h=None):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000010 if h is None:
Benjamin Petersonc6ad7942008-07-23 13:25:06 +000011 if isinstance(file, basestring):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000012 f = open(file, 'rb')
13 h = f.read(32)
14 else:
15 location = file.tell()
16 h = file.read(32)
17 file.seek(location)
Tim Peters07e99cb2001-01-14 23:47:14 +000018 f = None
Guido van Rossum54f22ed2000-02-04 15:10:34 +000019 else:
20 f = None
21 try:
22 for tf in tests:
23 res = tf(h, f)
24 if res:
25 return res
26 finally:
27 if f: f.close()
28 return None
Guido van Rossum1c34fc71992-05-27 14:06:59 +000029
30
31#---------------------------------#
32# Subroutines per image file type #
33#---------------------------------#
34
35tests = []
36
Benjamin Peterson4acb1892008-08-16 16:29:02 +000037def test_jpeg(h, f):
38 """JPEG data in JFIF format"""
39 if h[6:10] == 'JFIF':
40 return 'jpeg'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000041
Benjamin Peterson4acb1892008-08-16 16:29:02 +000042tests.append(test_jpeg)
43
44def test_exif(h, f):
45 """JPEG data in Exif format"""
46 if h[6:10] == 'Exif':
47 return 'jpeg'
48
49tests.append(test_exif)
50
51def test_png(h, f):
52 if h[:8] == "\211PNG\r\n\032\n":
53 return 'png'
54
55tests.append(test_png)
Guido van Rossum1c34fc71992-05-27 14:06:59 +000056
57def test_gif(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000058 """GIF ('87 and '89 variants)"""
59 if h[:6] in ('GIF87a', 'GIF89a'):
60 return 'gif'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000061
62tests.append(test_gif)
63
Benjamin Peterson4acb1892008-08-16 16:29:02 +000064def test_tiff(h, f):
65 """TIFF (can be in Motorola or Intel byte order)"""
66 if h[:2] in ('MM', 'II'):
67 return 'tiff'
68
69tests.append(test_tiff)
70
71def test_rgb(h, f):
72 """SGI image library"""
73 if h[:2] == '\001\332':
74 return 'rgb'
75
76tests.append(test_rgb)
77
Guido van Rossum2db91351992-10-18 17:09:59 +000078def test_pbm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000079 """PBM (portable bitmap)"""
80 if len(h) >= 3 and \
81 h[0] == 'P' and h[1] in '14' and h[2] in ' \t\n\r':
82 return 'pbm'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000083
Guido van Rossum2db91351992-10-18 17:09:59 +000084tests.append(test_pbm)
85
86def test_pgm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000087 """PGM (portable graymap)"""
88 if len(h) >= 3 and \
89 h[0] == 'P' and h[1] in '25' and h[2] in ' \t\n\r':
90 return 'pgm'
Guido van Rossum2db91351992-10-18 17:09:59 +000091
92tests.append(test_pgm)
93
94def test_ppm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000095 """PPM (portable pixmap)"""
96 if len(h) >= 3 and \
97 h[0] == 'P' and h[1] in '36' and h[2] in ' \t\n\r':
98 return 'ppm'
Guido van Rossum2db91351992-10-18 17:09:59 +000099
100tests.append(test_ppm)
Guido van Rossum1c34fc71992-05-27 14:06:59 +0000101
Guido van Rossum1c34fc71992-05-27 14:06:59 +0000102def test_rast(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000103 """Sun raster file"""
104 if h[:4] == '\x59\xA6\x6A\x95':
105 return 'rast'
Guido van Rossum1c34fc71992-05-27 14:06:59 +0000106
107tests.append(test_rast)
108
Guido van Rossum05b55e71992-06-03 16:48:44 +0000109def test_xbm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000110 """X bitmap (X10 or X11)"""
111 s = '#define '
112 if h[:len(s)] == s:
113 return 'xbm'
Guido van Rossum05b55e71992-06-03 16:48:44 +0000114
115tests.append(test_xbm)
116
Guido van Rossum9e330741997-04-11 18:59:38 +0000117def test_bmp(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000118 if h[:2] == 'BM':
119 return 'bmp'
Tim Peters07e99cb2001-01-14 23:47:14 +0000120
Guido van Rossum9e330741997-04-11 18:59:38 +0000121tests.append(test_bmp)
122
Guido van Rossum1c34fc71992-05-27 14:06:59 +0000123#--------------------#
124# Small test program #
125#--------------------#
126
127def test():
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000128 import sys
129 recursive = 0
130 if sys.argv[1:] and sys.argv[1] == '-r':
131 del sys.argv[1:2]
132 recursive = 1
133 try:
134 if sys.argv[1:]:
135 testall(sys.argv[1:], recursive, 1)
136 else:
137 testall(['.'], recursive, 1)
138 except KeyboardInterrupt:
139 sys.stderr.write('\n[Interrupted]\n')
140 sys.exit(1)
Guido van Rossum1c34fc71992-05-27 14:06:59 +0000141
142def testall(list, recursive, toplevel):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000143 import sys
144 import os
145 for filename in list:
146 if os.path.isdir(filename):
147 print filename + '/:',
148 if recursive or toplevel:
149 print 'recursing down:'
150 import glob
151 names = glob.glob(os.path.join(filename, '*'))
152 testall(names, recursive, 0)
153 else:
154 print '*** directory (use -r) ***'
155 else:
156 print filename + ':',
157 sys.stdout.flush()
158 try:
159 print what(filename)
160 except IOError:
161 print '*** not found ***'