blob: add2ea8898395e8052d7d38fb860a68f38ba49ef [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 Storchaka91b0bc22014-01-25 19:43:02 +020010 f = None
Guido van Rossum54f22ed2000-02-04 15:10:34 +000011 try:
Serhiy Storchaka91b0bc22014-01-25 19:43:02 +020012 if h is None:
13 if isinstance(file, str):
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 Peterson0b952902008-08-16 16:48:16 +000035def test_jpeg(h, f):
36 """JPEG data in JFIF or Exif format"""
37 if h[6:10] in (b'JFIF', b'Exif'):
38 return 'jpeg'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000039
Benjamin Peterson0b952902008-08-16 16:48:16 +000040tests.append(test_jpeg)
41
42def test_png(h, f):
43 if h.startswith(b'\211PNG\r\n\032\n'):
44 return 'png'
45
46tests.append(test_png)
Guido van Rossum1c34fc71992-05-27 14:06:59 +000047
48def test_gif(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000049 """GIF ('87 and '89 variants)"""
Barry Warsaw72937f32007-08-12 14:37:20 +000050 if h[:6] in (b'GIF87a', b'GIF89a'):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000051 return 'gif'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000052
53tests.append(test_gif)
54
Benjamin Peterson0b952902008-08-16 16:48:16 +000055def test_tiff(h, f):
56 """TIFF (can be in Motorola or Intel byte order)"""
57 if h[:2] in (b'MM', b'II'):
58 return 'tiff'
59
60tests.append(test_tiff)
61
62def test_rgb(h, f):
63 """SGI image library"""
64 if h.startswith(b'\001\332'):
65 return 'rgb'
66
67tests.append(test_rgb)
68
Guido van Rossum2db91351992-10-18 17:09:59 +000069def test_pbm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000070 """PBM (portable bitmap)"""
71 if len(h) >= 3 and \
Guido van Rossumc9341282007-08-13 17:50:00 +000072 h[0] == ord(b'P') and h[1] in b'14' and h[2] in b' \t\n\r':
Guido van Rossum54f22ed2000-02-04 15:10:34 +000073 return 'pbm'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000074
Guido van Rossum2db91351992-10-18 17:09:59 +000075tests.append(test_pbm)
76
77def test_pgm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000078 """PGM (portable graymap)"""
79 if len(h) >= 3 and \
Guido van Rossumc9341282007-08-13 17:50:00 +000080 h[0] == ord(b'P') and h[1] in b'25' and h[2] in b' \t\n\r':
Guido van Rossum54f22ed2000-02-04 15:10:34 +000081 return 'pgm'
Guido van Rossum2db91351992-10-18 17:09:59 +000082
83tests.append(test_pgm)
84
85def test_ppm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000086 """PPM (portable pixmap)"""
87 if len(h) >= 3 and \
Guido van Rossumc9341282007-08-13 17:50:00 +000088 h[0] == ord(b'P') and h[1] in b'36' and h[2] in b' \t\n\r':
Guido van Rossum54f22ed2000-02-04 15:10:34 +000089 return 'ppm'
Guido van Rossum2db91351992-10-18 17:09:59 +000090
91tests.append(test_ppm)
Guido van Rossum1c34fc71992-05-27 14:06:59 +000092
Guido van Rossum1c34fc71992-05-27 14:06:59 +000093def test_rast(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000094 """Sun raster file"""
Guido van Rossumc9341282007-08-13 17:50:00 +000095 if h.startswith(b'\x59\xA6\x6A\x95'):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000096 return 'rast'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000097
98tests.append(test_rast)
99
Guido van Rossum05b55e71992-06-03 16:48:44 +0000100def test_xbm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000101 """X bitmap (X10 or X11)"""
Guido van Rossumc9341282007-08-13 17:50:00 +0000102 if h.startswith(b'#define '):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000103 return 'xbm'
Guido van Rossum05b55e71992-06-03 16:48:44 +0000104
105tests.append(test_xbm)
106
Guido van Rossum9e330741997-04-11 18:59:38 +0000107def test_bmp(h, f):
Guido van Rossumc9341282007-08-13 17:50:00 +0000108 if h.startswith(b'BM'):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000109 return 'bmp'
Tim Peters07e99cb2001-01-14 23:47:14 +0000110
Guido van Rossum9e330741997-04-11 18:59:38 +0000111tests.append(test_bmp)
112
Guido van Rossum1c34fc71992-05-27 14:06:59 +0000113#--------------------#
114# Small test program #
115#--------------------#
116
117def test():
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000118 import sys
119 recursive = 0
120 if sys.argv[1:] and sys.argv[1] == '-r':
121 del sys.argv[1:2]
122 recursive = 1
123 try:
124 if sys.argv[1:]:
125 testall(sys.argv[1:], recursive, 1)
126 else:
127 testall(['.'], recursive, 1)
128 except KeyboardInterrupt:
129 sys.stderr.write('\n[Interrupted]\n')
130 sys.exit(1)
Guido van Rossum1c34fc71992-05-27 14:06:59 +0000131
132def testall(list, recursive, toplevel):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000133 import sys
134 import os
135 for filename in list:
136 if os.path.isdir(filename):
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000137 print(filename + '/:', end=' ')
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000138 if recursive or toplevel:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000139 print('recursing down:')
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000140 import glob
141 names = glob.glob(os.path.join(filename, '*'))
142 testall(names, recursive, 0)
143 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000144 print('*** directory (use -r) ***')
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000145 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000146 print(filename + ':', end=' ')
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000147 sys.stdout.flush()
148 try:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000149 print(what(filename))
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200150 except OSError:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000151 print('*** not found ***')
Barry Warsaw72937f32007-08-12 14:37:20 +0000152
153if __name__ == '__main__':
154 test()