1 """Recognize image file formats based on their first few bytes.""" 2 3 __all__ = ["what"] 4 5 #-------------------------# 6 # Recognize image headers # 7 #-------------------------# 8 9 def what(file, h=None): 10 if h is None: 11 if isinstance(file, basestring): 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) 18 f = None 19 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 29 30 31 #---------------------------------# 32 # Subroutines per image file type # 33 #---------------------------------# 34 35 tests = [] 36 37 def test_jpeg(h, f): 38 """JPEG data in JFIF format""" 39 if h[6:10] == 'JFIF': 40 return 'jpeg' 41 42 tests.append(test_jpeg) 43 44 def test_exif(h, f): 45 """JPEG data in Exif format""" 46 if h[6:10] == 'Exif': 47 return 'jpeg' 48 49 tests.append(test_exif) 50 51 def test_png(h, f): 52 if h[:8] == "\211PNG\r\n\032\n": 53 return 'png' 54 55 tests.append(test_png) 56 57 def test_gif(h, f): 58 """GIF ('87 and '89 variants)""" 59 if h[:6] in ('GIF87a', 'GIF89a'): 60 return 'gif' 61 62 tests.append(test_gif) 63 64 def 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 69 tests.append(test_tiff) 70 71 def test_rgb(h, f): 72 """SGI image library""" 73 if h[:2] == '\001\332': 74 return 'rgb' 75 76 tests.append(test_rgb) 77 78 def test_pbm(h, f): 79 """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' 83 84 tests.append(test_pbm) 85 86 def test_pgm(h, f): 87 """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' 91 92 tests.append(test_pgm) 93 94 def test_ppm(h, f): 95 """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' 99 100 tests.append(test_ppm) 101 102 def test_rast(h, f): 103 """Sun raster file""" 104 if h[:4] == '\x59\xA6\x6A\x95': 105 return 'rast' 106 107 tests.append(test_rast) 108 109 def test_xbm(h, f): 110 """X bitmap (X10 or X11)""" 111 s = '#define ' 112 if h[:len(s)] == s: 113 return 'xbm' 114 115 tests.append(test_xbm) 116 117 def test_bmp(h, f): 118 if h[:2] == 'BM': 119 return 'bmp' 120 121 tests.append(test_bmp) 122 123 #--------------------# 124 # Small test program # 125 #--------------------# 126 127 def test(): 128 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) 141 142 def testall(list, recursive, toplevel): 143 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 ***' 162