blob: 38732e63158c781f06081cc69c1c4abd3ce047eb [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:
11 if type(file) == type(''):
12 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
37def test_rgb(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000038 """SGI image library"""
Guido van Rossumc9341282007-08-13 17:50:00 +000039 if h.startswith(b'\001\332'):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000040 return 'rgb'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000041
42tests.append(test_rgb)
43
44def test_gif(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000045 """GIF ('87 and '89 variants)"""
Barry Warsaw72937f32007-08-12 14:37:20 +000046 if h[:6] in (b'GIF87a', b'GIF89a'):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000047 return 'gif'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000048
49tests.append(test_gif)
50
Guido van Rossum2db91351992-10-18 17:09:59 +000051def test_pbm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000052 """PBM (portable bitmap)"""
53 if len(h) >= 3 and \
Guido van Rossumc9341282007-08-13 17:50:00 +000054 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 +000055 return 'pbm'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000056
Guido van Rossum2db91351992-10-18 17:09:59 +000057tests.append(test_pbm)
58
59def test_pgm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000060 """PGM (portable graymap)"""
61 if len(h) >= 3 and \
Guido van Rossumc9341282007-08-13 17:50:00 +000062 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 +000063 return 'pgm'
Guido van Rossum2db91351992-10-18 17:09:59 +000064
65tests.append(test_pgm)
66
67def test_ppm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000068 """PPM (portable pixmap)"""
69 if len(h) >= 3 and \
Guido van Rossumc9341282007-08-13 17:50:00 +000070 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 +000071 return 'ppm'
Guido van Rossum2db91351992-10-18 17:09:59 +000072
73tests.append(test_ppm)
Guido van Rossum1c34fc71992-05-27 14:06:59 +000074
75def test_tiff(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000076 """TIFF (can be in Motorola or Intel byte order)"""
Barry Warsaw72937f32007-08-12 14:37:20 +000077 if h[:2] in (b'MM', b'II'):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000078 return 'tiff'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000079
80tests.append(test_tiff)
81
82def test_rast(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000083 """Sun raster file"""
Guido van Rossumc9341282007-08-13 17:50:00 +000084 if h.startswith(b'\x59\xA6\x6A\x95'):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000085 return 'rast'
Guido van Rossum1c34fc71992-05-27 14:06:59 +000086
87tests.append(test_rast)
88
Guido van Rossum05b55e71992-06-03 16:48:44 +000089def test_xbm(h, f):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000090 """X bitmap (X10 or X11)"""
Guido van Rossumc9341282007-08-13 17:50:00 +000091 if h.startswith(b'#define '):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000092 return 'xbm'
Guido van Rossum05b55e71992-06-03 16:48:44 +000093
94tests.append(test_xbm)
95
Guido van Rossum5cfa5df1993-06-23 09:30:50 +000096def test_jpeg(h, f):
Guido van Rossumc9341282007-08-13 17:50:00 +000097 """JPEG data in JFIF or Exif format"""
98 if h[6:10] in (b'JFIF', b'Exif'):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000099 return 'jpeg'
Guido van Rossum5cfa5df1993-06-23 09:30:50 +0000100
101tests.append(test_jpeg)
Guido van Rossum1c34fc71992-05-27 14:06:59 +0000102
Guido van Rossum9e330741997-04-11 18:59:38 +0000103def test_bmp(h, f):
Guido van Rossumc9341282007-08-13 17:50:00 +0000104 if h.startswith(b'BM'):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000105 return 'bmp'
Tim Peters07e99cb2001-01-14 23:47:14 +0000106
Guido van Rossum9e330741997-04-11 18:59:38 +0000107tests.append(test_bmp)
108
109def test_png(h, f):
Guido van Rossumc9341282007-08-13 17:50:00 +0000110 if h.startswith(b'\211PNG\r\n\032\n'):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000111 return 'png'
Guido van Rossum9e330741997-04-11 18:59:38 +0000112
113tests.append(test_png)
114
Guido van Rossum1c34fc71992-05-27 14:06:59 +0000115#--------------------#
116# Small test program #
117#--------------------#
118
119def test():
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000120 import sys
121 recursive = 0
122 if sys.argv[1:] and sys.argv[1] == '-r':
123 del sys.argv[1:2]
124 recursive = 1
125 try:
126 if sys.argv[1:]:
127 testall(sys.argv[1:], recursive, 1)
128 else:
129 testall(['.'], recursive, 1)
130 except KeyboardInterrupt:
131 sys.stderr.write('\n[Interrupted]\n')
132 sys.exit(1)
Guido van Rossum1c34fc71992-05-27 14:06:59 +0000133
134def testall(list, recursive, toplevel):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000135 import sys
136 import os
137 for filename in list:
138 if os.path.isdir(filename):
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000139 print(filename + '/:', end=' ')
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000140 if recursive or toplevel:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000141 print('recursing down:')
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000142 import glob
143 names = glob.glob(os.path.join(filename, '*'))
144 testall(names, recursive, 0)
145 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000146 print('*** directory (use -r) ***')
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000147 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000148 print(filename + ':', end=' ')
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000149 sys.stdout.flush()
150 try:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000151 print(what(filename))
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000152 except IOError:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000153 print('*** not found ***')
Barry Warsaw72937f32007-08-12 14:37:20 +0000154
155if __name__ == '__main__':
156 test()