14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""Recognize image file formats based on their first few bytes.""" 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__all__ = ["what"] 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#-------------------------# 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Recognize image headers # 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#-------------------------# 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef what(file, h=None): 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if h is None: 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isinstance(file, basestring): 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm f = open(file, 'rb') 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm h = f.read(32) 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm location = file.tell() 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm h = file.read(32) 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file.seek(location) 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm f = None 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm f = None 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for tf in tests: 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = tf(h, f) 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if res: 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return res 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if f: f.close() 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return None 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#---------------------------------# 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Subroutines per image file type # 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#---------------------------------# 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtests = [] 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_jpeg(h, f): 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """JPEG data in JFIF format""" 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if h[6:10] == 'JFIF': 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'jpeg' 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtests.append(test_jpeg) 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_exif(h, f): 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """JPEG data in Exif format""" 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if h[6:10] == 'Exif': 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'jpeg' 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtests.append(test_exif) 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_png(h, f): 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if h[:8] == "\211PNG\r\n\032\n": 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'png' 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtests.append(test_png) 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_gif(h, f): 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """GIF ('87 and '89 variants)""" 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if h[:6] in ('GIF87a', 'GIF89a'): 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'gif' 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtests.append(test_gif) 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_tiff(h, f): 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """TIFF (can be in Motorola or Intel byte order)""" 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if h[:2] in ('MM', 'II'): 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'tiff' 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtests.append(test_tiff) 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_rgb(h, f): 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """SGI image library""" 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if h[:2] == '\001\332': 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'rgb' 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtests.append(test_rgb) 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_pbm(h, f): 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """PBM (portable bitmap)""" 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if len(h) >= 3 and \ 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm h[0] == 'P' and h[1] in '14' and h[2] in ' \t\n\r': 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'pbm' 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtests.append(test_pbm) 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_pgm(h, f): 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """PGM (portable graymap)""" 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if len(h) >= 3 and \ 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm h[0] == 'P' and h[1] in '25' and h[2] in ' \t\n\r': 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'pgm' 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtests.append(test_pgm) 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_ppm(h, f): 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """PPM (portable pixmap)""" 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if len(h) >= 3 and \ 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm h[0] == 'P' and h[1] in '36' and h[2] in ' \t\n\r': 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'ppm' 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtests.append(test_ppm) 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_rast(h, f): 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Sun raster file""" 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if h[:4] == '\x59\xA6\x6A\x95': 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'rast' 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtests.append(test_rast) 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_xbm(h, f): 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """X bitmap (X10 or X11)""" 1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s = '#define ' 1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if h[:len(s)] == s: 1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'xbm' 1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtests.append(test_xbm) 1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_bmp(h, f): 1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if h[:2] == 'BM': 1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'bmp' 1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtests.append(test_bmp) 1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#--------------------# 1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Small test program # 1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#--------------------# 1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test(): 1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import sys 1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm recursive = 0 1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if sys.argv[1:] and sys.argv[1] == '-r': 1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del sys.argv[1:2] 1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm recursive = 1 1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if sys.argv[1:]: 1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm testall(sys.argv[1:], recursive, 1) 1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm testall(['.'], recursive, 1) 1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except KeyboardInterrupt: 1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.stderr.write('\n[Interrupted]\n') 1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.exit(1) 1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef testall(list, recursive, toplevel): 1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import sys 1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import os 1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for filename in list: 1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if os.path.isdir(filename): 1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print filename + '/:', 1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if recursive or toplevel: 1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print 'recursing down:' 1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import glob 1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm names = glob.glob(os.path.join(filename, '*')) 1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm testall(names, recursive, 0) 1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print '*** directory (use -r) ***' 1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print filename + ':', 1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.stdout.flush() 1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print what(filename) 1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except IOError: 1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print '*** not found ***' 162