util: Use python names consistent with u_format.h
[mesa.git] / src / gallium / auxiliary / util / u_format_parse.py
1 #!/usr/bin/env python
2
3 '''
4 /**************************************************************************
5 *
6 * Copyright 2009 VMware, Inc.
7 * All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the
11 * "Software"), to deal in the Software without restriction, including
12 * without limitation the rights to use, copy, modify, merge, publish,
13 * distribute, sub license, and/or sell copies of the Software, and to
14 * permit persons to whom the Software is furnished to do so, subject to
15 * the following conditions:
16 *
17 * The above copyright notice and this permission notice (including the
18 * next paragraph) shall be included in all copies or substantial portions
19 * of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
25 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 *
29 **************************************************************************/
30 '''
31
32
33 VOID, UNSIGNED, SIGNED, FIXED, FLOAT = range(5)
34
35 SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W, SWIZZLE_0, SWIZZLE_1, SWIZZLE_NONE, = range(7)
36
37 PLAIN = 'plain'
38
39
40 def is_pot(x):
41 return (x & (x - 1)) == 0;
42
43
44 class Channel:
45 '''Describe the channel of a color channel.'''
46
47 def __init__(self, type, norm, size):
48 self.type = type
49 self.norm = norm
50 self.size = size
51 self.sign = type in (SIGNED, FIXED, FLOAT)
52
53 def __str__(self):
54 s = str(self.type)
55 if self.norm:
56 s += 'n'
57 s += str(self.size)
58 return s
59
60 def __eq__(self, other):
61 return self.type == other.type and self.norm == other.norm and self.size == other.size
62
63
64 class Format:
65 '''Describe a pixel format.'''
66
67 def __init__(self, name, layout, block_width, block_height, channels, swizzles, colorspace):
68 self.name = name
69 self.layout = layout
70 self.block_width = block_width
71 self.block_height = block_height
72 self.channels = channels
73 self.swizzles = swizzles
74 self.name = name
75 self.colorspace = colorspace
76
77 def __str__(self):
78 return self.name
79
80 def short_name(self):
81 '''Make up a short norm for a format, suitable to be used as suffix in
82 function names.'''
83
84 name = self.name
85 if name.startswith('PIPE_FORMAT_'):
86 name = name[len('PIPE_FORMAT_'):]
87 name = name.lower()
88 return name
89
90 def block_size(self):
91 size = 0
92 for channel in self.channels:
93 size += channel.size
94 return size
95
96 def nr_channels(self):
97 nr_channels = 0
98 for channel in self.channels:
99 if channel.size:
100 nr_channels += 1
101 return nr_channels
102
103 def is_array(self):
104 ref_channel = self.channels[0]
105 for channel in self.channels[1:]:
106 if channel.size and (channel.size != ref_channel.size or channel.size % 8):
107 return False
108 return True
109
110 def is_mixed(self):
111 ref_channel = self.channels[0]
112 for channel in self.channels[1:]:
113 if channel.type != VOID:
114 if channel.type != ref_channel.type:
115 return True
116 if channel.norm != ref_channel.norm:
117 return True
118 return False
119
120 def is_pot(self):
121 return is_pot(self.block_size())
122
123 def is_int(self):
124 for channel in self.channels:
125 if channel.type not in (VOID, UNSIGNED, SIGNED):
126 return False
127 return True
128
129 def is_float(self):
130 for channel in self.channels:
131 if channel.type not in (VOID, FLOAT):
132 return False
133 return True
134
135 def stride(self):
136 return self.block_size()/8
137
138
139 _type_parse_map = {
140 '': VOID,
141 'x': VOID,
142 'u': UNSIGNED,
143 's': SIGNED,
144 'h': FIXED,
145 'f': FLOAT,
146 }
147
148 _swizzle_parse_map = {
149 'x': SWIZZLE_X,
150 'y': SWIZZLE_Y,
151 'z': SWIZZLE_Z,
152 'w': SWIZZLE_W,
153 '0': SWIZZLE_0,
154 '1': SWIZZLE_1,
155 '_': SWIZZLE_NONE,
156 }
157
158 def parse(filename):
159 '''Parse the format descrition in CSV format in terms of the
160 Channel and Format classes above.'''
161
162 stream = open(filename)
163 formats = []
164 for line in stream:
165 try:
166 comment = line.index('#')
167 except ValueError:
168 pass
169 else:
170 line = line[:comment]
171 line = line.strip()
172 if not line:
173 continue
174 fields = [field.strip() for field in line.split(',')]
175 name = fields[0]
176 layout = fields[1]
177 block_width, block_height = map(int, fields[2:4])
178 channels = []
179 for field in fields[4:8]:
180 if field:
181 type = _type_parse_map[field[0]]
182 if field[1] == 'n':
183 norm = True
184 size = int(field[2:])
185 else:
186 norm = False
187 size = int(field[1:])
188 else:
189 type = VOID
190 norm = False
191 size = 0
192 channel = Channel(type, norm, size)
193 channels.append(channel)
194 swizzles = [_swizzle_parse_map[swizzle] for swizzle in fields[8]]
195 colorspace = fields[9]
196 formats.append(Format(name, layout, block_width, block_height, channels, swizzles, colorspace))
197 return formats
198