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     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