1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#!/usr/bin/env python
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org'''
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 VMware, Inc.
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org'''
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgVOID, UNSIGNED, SIGNED, FIXED, FLOAT = range(5)
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W, SWIZZLE_0, SWIZZLE_1, SWIZZLE_NONE, = range(7)
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgPLAIN = 'plain'
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgRGB = 'rgb'
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSRGB = 'srgb'
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgYUV = 'yuv'
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgZS = 'zs'
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdef is_pot(x):
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (x & (x - 1)) == 0
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgVERY_LARGE = 99999999999999999999999
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass Channel:
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    '''Describe the channel of a color channel.'''
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def __init__(self, type, norm, pure, size, name = ''):
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        self.type = type
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        self.norm = norm
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        self.pure = pure
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        self.size = size
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        self.sign = type in (SIGNED, FIXED, FLOAT)
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        self.name = name
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def __str__(self):
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        s = str(self.type)
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.norm:
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            s += 'n'
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.pure:
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            s += 'p'
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        s += str(self.size)
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return s
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def __eq__(self, other):
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return self.type == other.type and self.norm == other.norm and self.pure == other.pure and self.size == other.size
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def max(self):
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        '''Maximum representable number.'''
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.type == FLOAT:
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return VERY_LARGE
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.type == FIXED:
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return (1 << (self.size/2)) - 1
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.norm:
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return 1
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.type == UNSIGNED:
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return (1 << self.size) - 1
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.type == SIGNED:
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return (1 << (self.size - 1)) - 1
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        assert False
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def min(self):
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        '''Minimum representable number.'''
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.type == FLOAT:
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return -VERY_LARGE
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.type == FIXED:
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return -(1 << (self.size/2))
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.type == UNSIGNED:
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return 0
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.norm:
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return -1
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.type == SIGNED:
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return -(1 << (self.size - 1))
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        assert False
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass Format:
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    '''Describe a pixel format.'''
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def __init__(self, name, layout, block_width, block_height, channels, swizzles, colorspace):
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        self.name = name
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        self.layout = layout
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        self.block_width = block_width
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        self.block_height = block_height
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        self.channels = channels
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        self.swizzles = swizzles
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        self.name = name
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        self.colorspace = colorspace
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def __str__(self):
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return self.name
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def short_name(self):
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        '''Make up a short norm for a format, suitable to be used as suffix in
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        function names.'''
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        name = self.name
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if name.startswith('PIPE_FORMAT_'):
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            name = name[len('PIPE_FORMAT_'):]
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        name = name.lower()
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return name
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def block_size(self):
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        size = 0
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        for channel in self.channels:
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            size += channel.size
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return size
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def nr_channels(self):
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        nr_channels = 0
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        for channel in self.channels:
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if channel.size:
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                nr_channels += 1
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return nr_channels
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def is_array(self):
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.layout != PLAIN:
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return False
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ref_channel = self.channels[0]
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        for channel in self.channels[1:]:
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if channel.size and (channel.size != ref_channel.size or channel.size % 8):
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                return False
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return True
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def is_mixed(self):
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.layout != PLAIN:
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return False
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ref_channel = self.channels[0]
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if ref_channel.type == VOID:
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           ref_channel = self.channels[1]
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        for channel in self.channels[1:]:
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if channel.type != VOID:
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                if channel.type != ref_channel.type:
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    return True
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                if channel.norm != ref_channel.norm:
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    return True
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                if channel.pure != ref_channel.pure:
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    return True
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return False
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def is_pot(self):
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return is_pot(self.block_size())
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def is_int(self):
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.layout != PLAIN:
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return False
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        for channel in self.channels:
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if channel.type not in (VOID, UNSIGNED, SIGNED):
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                return False
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return True
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def is_float(self):
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.layout != PLAIN:
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return False
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        for channel in self.channels:
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if channel.type not in (VOID, FLOAT):
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                return False
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return True
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def is_bitmask(self):
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.layout != PLAIN:
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return False
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if self.block_size() not in (8, 16, 32):
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return False
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        for channel in self.channels:
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if channel.type not in (VOID, UNSIGNED, SIGNED):
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                return False
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return True
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def inv_swizzles(self):
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        '''Return an array[4] of inverse swizzle terms'''
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        '''Only pick the first matching value to avoid l8 getting blue and i8 getting alpha'''
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        inv_swizzle = [None]*4
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        for i in range(4):
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            swizzle = self.swizzles[i]
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if swizzle < 4 and inv_swizzle[swizzle] == None:
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                inv_swizzle[swizzle] = i
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return inv_swizzle
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    def stride(self):
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return self.block_size()/8
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_type_parse_map = {
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    '':  VOID,
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    'x': VOID,
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    'u': UNSIGNED,
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    's': SIGNED,
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    'h': FIXED,
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    'f': FLOAT,
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_swizzle_parse_map = {
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    'x': SWIZZLE_X,
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    'y': SWIZZLE_Y,
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    'z': SWIZZLE_Z,
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    'w': SWIZZLE_W,
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    '0': SWIZZLE_0,
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    '1': SWIZZLE_1,
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    '_': SWIZZLE_NONE,
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdef parse(filename):
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    '''Parse the format descrition in CSV format in terms of the
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Channel and Format classes above.'''
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    stream = open(filename)
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    formats = []
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for line in stream:
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        try:
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            comment = line.index('#')
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        except ValueError:
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            pass
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        else:
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            line = line[:comment]
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        line = line.strip()
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if not line:
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            continue
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        fields = [field.strip() for field in line.split(',')]
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        name = fields[0]
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        layout = fields[1]
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        block_width, block_height = map(int, fields[2:4])
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        swizzles = [_swizzle_parse_map[swizzle] for swizzle in fields[8]]
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        colorspace = fields[9]
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if layout == PLAIN:
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            names = ['']*4
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if colorspace in (RGB, SRGB):
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                for i in range(4):
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    swizzle = swizzles[i]
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    if swizzle < 4:
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        names[swizzle] += 'rgba'[i]
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            elif colorspace == ZS:
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                for i in range(4):
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    swizzle = swizzles[i]
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    if swizzle < 4:
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        names[swizzle] += 'zs'[i]
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else:
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                assert False
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            for i in range(4):
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                if names[i] == '':
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    names[i] = 'x'
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        else:
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            names = ['x', 'y', 'z', 'w']
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        channels = []
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        for i in range(0, 4):
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            field = fields[4 + i]
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if field:
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                type = _type_parse_map[field[0]]
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                if field[1] == 'n':
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    norm = True
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    pure = False
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    size = int(field[2:])
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                elif field[1] == 'p':
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    pure = True
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    norm = False
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    size = int(field[2:])
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                else:
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    norm = False
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    pure = False
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    size = int(field[1:])
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else:
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                type = VOID
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                norm = False
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                pure = False
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                size = 0
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            channel = Channel(type, norm, pure, size, names[i])
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            channels.append(channel)
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        format = Format(name, layout, block_width, block_height, channels, swizzles, colorspace)
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        formats.append(format)
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return formats
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
305