1"""Recognize image file formats based on their first few bytes.""" 2 3__all__ = ["what"] 4 5#-------------------------# 6# Recognize image headers # 7#-------------------------# 8 9def what(file, h=None): 10 f = None 11 try: 12 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) 20 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 27 28 29#---------------------------------# 30# Subroutines per image file type # 31#---------------------------------# 32 33tests = [] 34 35def test_jpeg(h, f): 36 """JPEG data in JFIF format""" 37 if h[6:10] == 'JFIF': 38 return 'jpeg' 39 40tests.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) 54 55def test_gif(h, f): 56 """GIF ('87 and '89 variants)""" 57 if h[:6] in ('GIF87a', 'GIF89a'): 58 return 'gif' 59 60tests.append(test_gif) 61 62def 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 76def test_pbm(h, f): 77 """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' 81 82tests.append(test_pbm) 83 84def test_pgm(h, f): 85 """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' 89 90tests.append(test_pgm) 91 92def test_ppm(h, f): 93 """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' 97 98tests.append(test_ppm) 99 100def test_rast(h, f): 101 """Sun raster file""" 102 if h[:4] == '\x59\xA6\x6A\x95': 103 return 'rast' 104 105tests.append(test_rast) 106 107def test_xbm(h, f): 108 """X bitmap (X10 or X11)""" 109 s = '#define ' 110 if h[:len(s)] == s: 111 return 'xbm' 112 113tests.append(test_xbm) 114 115def test_bmp(h, f): 116 if h[:2] == 'BM': 117 return 'bmp' 118 119tests.append(test_bmp) 120 121#--------------------# 122# Small test program # 123#--------------------# 124 125def test(): 126 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) 139 140def testall(list, recursive, toplevel): 141 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 ***' 160