Home | History | Annotate | Download | only in Lib
      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     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 
     33 tests = []
     34 
     35 def test_jpeg(h, f):
     36     """JPEG data in JFIF format"""
     37     if h[6:10] == 'JFIF':
     38         return 'jpeg'
     39 
     40 tests.append(test_jpeg)
     41 
     42 def test_exif(h, f):
     43     """JPEG data in Exif format"""
     44     if h[6:10] == 'Exif':
     45         return 'jpeg'
     46 
     47 tests.append(test_exif)
     48 
     49 def test_png(h, f):
     50     if h[:8] == "\211PNG\r\n\032\n":
     51         return 'png'
     52 
     53 tests.append(test_png)
     54 
     55 def test_gif(h, f):
     56     """GIF ('87 and '89 variants)"""
     57     if h[:6] in ('GIF87a', 'GIF89a'):
     58         return 'gif'
     59 
     60 tests.append(test_gif)
     61 
     62 def 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 
     67 tests.append(test_tiff)
     68 
     69 def test_rgb(h, f):
     70     """SGI image library"""
     71     if h[:2] == '\001\332':
     72         return 'rgb'
     73 
     74 tests.append(test_rgb)
     75 
     76 def 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 
     82 tests.append(test_pbm)
     83 
     84 def 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 
     90 tests.append(test_pgm)
     91 
     92 def 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 
     98 tests.append(test_ppm)
     99 
    100 def test_rast(h, f):
    101     """Sun raster file"""
    102     if h[:4] == '\x59\xA6\x6A\x95':
    103         return 'rast'
    104 
    105 tests.append(test_rast)
    106 
    107 def test_xbm(h, f):
    108     """X bitmap (X10 or X11)"""
    109     s = '#define '
    110     if h[:len(s)] == s:
    111         return 'xbm'
    112 
    113 tests.append(test_xbm)
    114 
    115 def test_bmp(h, f):
    116     if h[:2] == 'BM':
    117         return 'bmp'
    118 
    119 tests.append(test_bmp)
    120 
    121 #--------------------#
    122 # Small test program #
    123 #--------------------#
    124 
    125 def 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 
    140 def 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