1 # Module with PixelType descrition class
2 # 2011 - Tomas Gavenciak <gavento@ucw.cz>
16 ## *Global* dictionary of all pixeltypes { name : PixelType }
19 ## *Global* set of all encountered channel names
22 ## Allowed bit-sizes of pixels
23 bitsizes
= [1,2,4,8,16,24,32]
26 bit_endians
= ['LE', 'BE']
28 ## Create pixel-size suffix (16BPP or 4BPP_LE)
29 def get_size_suffix(bpp
, bit_endian
):
30 assert bpp
in bitsizes
31 assert bit_endian
in bit_endians
32 size_suffix
= '%dBPP' % (bpp
)
34 size_suffix
+= '_' + bit_endian
38 class PixelType(object):
39 """Representation of one GP_PixelType"""
40 def __init__(self
, name
, size
, chanslist
, number
=None, bit_endian
=None):
41 """`name` must be a valid C identifier
42 `size` is in bits, allowed are 1, 2, 4, 8, 16, 24, 32
43 `bit_endian` is order of 1,2,4BPP pixels in a byte, either 'BE' or 'LE'
44 `chanslist` is a list of triplets describing individual channels as
45 [ (`chan_name`, `bit_offset`, `bit_size`) ]
46 `chan_name` is usually one of: R, G, B, V (value, used for grayscale), A (opacity)
47 `number` is auto-assigned (internal use only)
49 assert re
.match('\A[A-Za-z][A-Za-z0-9_]*\Z', name
)
51 self
.chanslist
= chanslist
52 self
.chans
= dict() # { chan_name: (offset, size) }
53 # all types except UNKNOWN=0 must have one of these sizes
55 assert(size
in bitsizes
)
58 # bit_endian matters only for 1,2,4bpp
59 if size
>=8 and bit_endian
is None:
60 bit_endian
= bit_endians
[0]
61 assert bit_endian
in bit_endians
62 self
.bit_endian
= bit_endian
65 self
.size_suffix
= "INVALID"
67 self
.size_suffix
= get_size_suffix(self
.size
, self
.bit_endian
)
70 if number
is not None:
73 self
.number
= max([ptype
.number
for ptype
in pixeltypes
.values()] + [0]) + 1
75 # Verify channel bits for overlaps
76 # also builds a bit-map of the PixelType
77 self
.bits
= ['x']*size
79 assert c
[0] not in self
.chans
.keys()
81 for i
in range(c
[1],c
[1]+c
[2]):
83 assert(self
.bits
[i
]=='x')
86 assert self
.name
not in pixeltypes
.keys()
87 pixeltypes
[self
.name
] = self
88 channels
.update(set(self
.chans
.keys()))
91 return "<PixelType " + self
.name
+ ">"
93 if 0 not in pixeltypes
:
94 PixelType("UNKNOWN", 0, [], bit_endian
=bit_endians
[0], number
=0)