Commit | Line | Data |
---|---|---|
86530b38 AT |
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 type(file) == type(''): | |
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_rgb(h, f): | |
38 | """SGI image library""" | |
39 | if h[:2] == '\001\332': | |
40 | return 'rgb' | |
41 | ||
42 | tests.append(test_rgb) | |
43 | ||
44 | def test_gif(h, f): | |
45 | """GIF ('87 and '89 variants)""" | |
46 | if h[:6] in ('GIF87a', 'GIF89a'): | |
47 | return 'gif' | |
48 | ||
49 | tests.append(test_gif) | |
50 | ||
51 | def test_pbm(h, f): | |
52 | """PBM (portable bitmap)""" | |
53 | if len(h) >= 3 and \ | |
54 | h[0] == 'P' and h[1] in '14' and h[2] in ' \t\n\r': | |
55 | return 'pbm' | |
56 | ||
57 | tests.append(test_pbm) | |
58 | ||
59 | def test_pgm(h, f): | |
60 | """PGM (portable graymap)""" | |
61 | if len(h) >= 3 and \ | |
62 | h[0] == 'P' and h[1] in '25' and h[2] in ' \t\n\r': | |
63 | return 'pgm' | |
64 | ||
65 | tests.append(test_pgm) | |
66 | ||
67 | def test_ppm(h, f): | |
68 | """PPM (portable pixmap)""" | |
69 | if len(h) >= 3 and \ | |
70 | h[0] == 'P' and h[1] in '36' and h[2] in ' \t\n\r': | |
71 | return 'ppm' | |
72 | ||
73 | tests.append(test_ppm) | |
74 | ||
75 | def test_tiff(h, f): | |
76 | """TIFF (can be in Motorola or Intel byte order)""" | |
77 | if h[:2] in ('MM', 'II'): | |
78 | return 'tiff' | |
79 | ||
80 | tests.append(test_tiff) | |
81 | ||
82 | def test_rast(h, f): | |
83 | """Sun raster file""" | |
84 | if h[:4] == '\x59\xA6\x6A\x95': | |
85 | return 'rast' | |
86 | ||
87 | tests.append(test_rast) | |
88 | ||
89 | def test_xbm(h, f): | |
90 | """X bitmap (X10 or X11)""" | |
91 | s = '#define ' | |
92 | if h[:len(s)] == s: | |
93 | return 'xbm' | |
94 | ||
95 | tests.append(test_xbm) | |
96 | ||
97 | def test_jpeg(h, f): | |
98 | """JPEG data in JFIF format""" | |
99 | if h[6:10] == 'JFIF': | |
100 | return 'jpeg' | |
101 | ||
102 | tests.append(test_jpeg) | |
103 | ||
104 | def test_bmp(h, f): | |
105 | if h[:2] == 'BM': | |
106 | return 'bmp' | |
107 | ||
108 | tests.append(test_bmp) | |
109 | ||
110 | def test_png(h, f): | |
111 | if h[:8] == "\211PNG\r\n\032\n": | |
112 | return 'png' | |
113 | ||
114 | tests.append(test_png) | |
115 | ||
116 | #--------------------# | |
117 | # Small test program # | |
118 | #--------------------# | |
119 | ||
120 | def test(): | |
121 | import sys | |
122 | recursive = 0 | |
123 | if sys.argv[1:] and sys.argv[1] == '-r': | |
124 | del sys.argv[1:2] | |
125 | recursive = 1 | |
126 | try: | |
127 | if sys.argv[1:]: | |
128 | testall(sys.argv[1:], recursive, 1) | |
129 | else: | |
130 | testall(['.'], recursive, 1) | |
131 | except KeyboardInterrupt: | |
132 | sys.stderr.write('\n[Interrupted]\n') | |
133 | sys.exit(1) | |
134 | ||
135 | def testall(list, recursive, toplevel): | |
136 | import sys | |
137 | import os | |
138 | for filename in list: | |
139 | if os.path.isdir(filename): | |
140 | print filename + '/:', | |
141 | if recursive or toplevel: | |
142 | print 'recursing down:' | |
143 | import glob | |
144 | names = glob.glob(os.path.join(filename, '*')) | |
145 | testall(names, recursive, 0) | |
146 | else: | |
147 | print '*** directory (use -r) ***' | |
148 | else: | |
149 | print filename + ':', | |
150 | sys.stdout.flush() | |
151 | try: | |
152 | print what(filename) | |
153 | except IOError: | |
154 | print '*** not found ***' |