blob: fc864c3a2ee7472a708e1824c8a10851a55379fc [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):
Serhiy Storchaka1adbacf2014-01-25 19:42:27 +020010 f = None
Guido van Rossum54f22ed2000-02-04 15:10:34 +000011 try:
Serhiy Storchaka1adbacf2014-01-25 19:42:27 +020012 if h is None:
13 if isinstance(file, basestring):
14 f = open(file, 'rb')
15 h = f.read(32)
16 else:
17 location = file.tell()
18 h = file.read(32)
19 file.seek(location)
Guido van Rossum54f22ed2000-02-04 15:10:34 +000020 for tf in tests:
21 res = tf(h, f)
22 if res:
23 return res
24 finally:
25 if f: f.close()
26 return None
Guido van Rossum1c34fc71992-05-27 14:06:59 +000027
28
29#---------------------------------#
30# Subroutines per image file type #
31#---------------------------------#
32
33tests = []
34
Benjamin Peterson4acb1892008-08-16 16:29:02 +000035def test_jpeg(h, f):
36 """JPEG data in JFIF format"""
37 if h[6:10] == 'JFIF':
38 return 'jpeg'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000039
Benjamin Peterson4acb1892008-08-16 16:29:02 +000040tests.append(test_jpeg)
41
42def test_exif(h, f):
43 """JPEG data in Exif format"""
44 if h[6:10] == 'Exif':
45 return 'jpeg'
46
47tests.append(test_exif)
48
49def test_png(h, f):
50 if h[:8] == "\211PNG\r\n\032\n":
51 return 'png'
52
53tests.append(test_png)
Guido van Rossum1c34fc71992-05-27 14:06:59 +000054
55def test_gif(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000056 """GIF ('87 and '89 variants)"""
57 if h[:6] in ('GIF87a', 'GIF89a'):
58 return 'gif'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000059
60tests.append(test_gif)
61
Benjamin Peterson4acb1892008-08-16 16:29:02 +000062def test_tiff(h, f):
63 """TIFF (can be in Motorola or Intel byte order)"""
64 if h[:2] in ('MM', 'II'):
65 return 'tiff'
66
67tests.append(test_tiff)
68
69def test_rgb(h, f):
70 """SGI image library"""
71 if h[:2] == '\001\332':
72 return 'rgb'
73
74tests.append(test_rgb)
75
Guido van Rossum2db91351992-10-18 17:09:59 +000076def test_pbm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000077 """PBM (portable bitmap)"""
78 if len(h) >= 3 and \
79 h[0] == 'P' and h[1] in '14' and h[2] in ' \t\n\r':
80 return 'pbm'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000081
Guido van Rossum2db91351992-10-18 17:09:59 +000082tests.append(test_pbm)
83
84def test_pgm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000085 """PGM (portable graymap)"""
86 if len(h) >= 3 and \
87 h[0] == 'P' and h[1] in '25' and h[2] in ' \t\n\r':
88 return 'pgm'
Guido van Rossum2db91351992-10-18 17:09:59 +000089
90tests.append(test_pgm)
91
92def test_ppm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000093 """PPM (portable pixmap)"""
94 if len(h) >= 3 and \
95 h[0] == 'P' and h[1] in '36' and h[2] in ' \t\n\r':
96 return 'ppm'
Guido van Rossum2db91351992-10-18 17:09:59 +000097
98tests.append(test_ppm)
Guido van Rossum1c34fc71992-05-27 14:06:59 +000099
Guido van Rossum1c34fc71992-05-27 14:06:59 +0000100def test_rast(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000101 """Sun raster file"""
102 if h[:4] == '\x59\xA6\x6A\x95':
103 return 'rast'
Guido van Rossum1c34fc71992-05-27 14:06:59 +0000104
105tests.append(test_rast)
106
Guido van Rossum05b55e71992-06-03 16:48:44 +0000107def test_xbm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000108 """X bitmap (X10 or X11)"""
109 s = '#define '
110 if h[:len(s)] == s:
111 return 'xbm'
Guido van Rossum05b55e71992-06-03 16:48:44 +0000112
113tests.append(test_xbm)
114
Guido van Rossum9e330741997-04-11 18:59:38 +0000115def test_bmp(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000116 if h[:2] == 'BM':
117 return 'bmp'
Tim Peters07e99cb2001-01-14 23:47:14 +0000118
Guido van Rossum9e330741997-04-11 18:59:38 +0000119tests.append(test_bmp)
120
Guido van Rossum1c34fc71992-05-27 14:06:59 +0000121#--------------------#
122# Small test program #
123#--------------------#
124
125def test():
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000126 import sys
127 recursive = 0
128 if sys.argv[1:] and sys.argv[1] == '-r':
129 del sys.argv[1:2]
130 recursive = 1
131 try:
132 if sys.argv[1:]:
133 testall(sys.argv[1:], recursive, 1)
134 else:
135 testall(['.'], recursive, 1)
136 except KeyboardInterrupt:
137 sys.stderr.write('\n[Interrupted]\n')
138 sys.exit(1)
Guido van Rossum1c34fc71992-05-27 14:06:59 +0000139
140def testall(list, recursive, toplevel):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000141 import sys
142 import os
143 for filename in list:
144 if os.path.isdir(filename):
145 print filename + '/:',
146 if recursive or toplevel:
147 print 'recursing down:'
148 import glob
149 names = glob.glob(os.path.join(filename, '*'))
150 testall(names, recursive, 0)
151 else:
152 print '*** directory (use -r) ***'
153 else:
154 print filename + ':',
155 sys.stdout.flush()
156 try:
157 print what(filename)
158 except IOError:
159 print '*** not found ***'