4 The GFXprim uses python templating engine to generate code for different pixel
5 types. This is documentation to the engine internals.
10 The configuration which describes pixel layout could be found in root GFXprim
11 directory under name 'gfxprim_config.py' which is used to create objects
21 -------------------------------------------------------------------------------
22 class PixelSize(object):
27 self.bit_endian = bit_endian
29 def needs_bit_endian(self):
34 -------------------------------------------------------------------------------
36 The Pixel Size object represents pixel as a continous block of data.
38 The 'size' is size in bits and is sometimes called bpp which stands for "bits
39 per pixel". This number includes padding bits, if any.
41 The 'suffix' is a string used as a suffix for functions, macros and other
42 identifiers that operate with this pixel size.
44 The 'bit_endian' determines the ordering of pixel bits within a byte in bitmaps
45 and graymaps. This is significant in pixel types with pixel boundaries
46 within a byte, i.e. 1 bpp, 4 bpp or 17 bpp.
48 The function 'needs_bit_endian()' returns true for pixel sizes that are not
49 aligned to the whole bytes.
51 The bit endian can be either 'BE' or 'LE' (i.e. most significant bit left or
52 right in the bitmap). Usually, the bitmap is ordered with left bits earlier
53 in the memory, but the earlier/later relationship is important. This is
54 defined in terms of natural pixel ordering within the memory.
56 'BE' means that the earlier (usually left-most) pixels use the higher ("big")
57 bits of the byte. I.e. in 1 bpp, the first pixel would have value 128, the second 64
60 'LE' means that the earlier (usually left-most) pixels use the lower ("little")
61 bits of the byte. I.e. in 1 bpp, the first pixel would have value 1, the second 2,
62 the eight'th 128 and so on.
64 The following two figures describe bit layout in 1 bpp and 2 bpp
65 grayscale bitmaps. The rectangles in the figures represents bytes as they are
66 in the bitmap memory. The start of the image (i.e. topleft corner
67 and coodinates (0,0)) is on the left side.
68 The numbers describe position of the bit in the byte, 'i' representing
69 value '1<<i', that is 7-th bit representing value 128 and 0-th bit value 1.
74 ["graphviz", "bit-endian-be-1bit.png"]
75 ------------------------------------------------------------------------------
78 node [shape = record];
81 node0 [label = "{<e> ...}"];
82 node1 [label = "{7 | 6 | 5 | 4 | 3 | 2 | 1 | <e> 0}"];
83 node2 [label = "{<b> 7 | 6 | 5 | 4 | 3 | 2 | 1 | <e> 0}"];
84 node3 [label = "{<b> 7 | 6 | 5 | 4 | 3 | 2 | 1 | <e> 0}"];
85 node4 [label = "{<b> ...}"];
92 ------------------------------------------------------------------------------
94 ["graphviz", "bit-endian-be-2bits.png"]
95 ------------------------------------------------------------------------------
98 node [shape = record];
101 node0 [label = "{<e> ...}"];
102 node1 [label = "{7 6 | 5 4 | 3 2 | <e> 1 0}"];
103 node2 [label = "{<b> 7 6 | 5 4 | 3 2 | <e> 1 0}"];
104 node3 [label = "{<b> 7 6 | 5 4 | 3 2 | <e> 1 0}"];
105 node4 [label = "{<b> ...}"];
112 ------------------------------------------------------------------------------
117 ["graphviz", "bit-endian-le-1bit.png"]
118 ------------------------------------------------------------------------------
121 node [shape = record];
124 node0 [label = "{<e> ...}"];
125 node1 [label = "{0 | 1 | 2 | 3 | 4 | 5 | 6 | <e> 7}"];
126 node2 [label = "{<b> 0 | 1 | 2 | 3 | 4 | 5 | 6 | <e> 7}"];
127 node3 [label = "{<b> 0 | 1 | 2 | 3 | 4 | 5 | 6 | <e> 7}"];
128 node4 [label = "{<b> ...}"];
135 ------------------------------------------------------------------------------
137 ["graphviz", "bit-endian-le-2bits.png"]
138 ------------------------------------------------------------------------------
141 node [shape = record];
144 node0 [label = "<e> ..."];
145 node1 [label = "{1 0 | 3 2 | 5 4 | <e> 7 6}"];
146 node2 [label = "{<b> 1 0 | 3 2 | 5 4 | <e> 7 6}"];
147 node3 [label = "{<b> 1 0 | 3 2 | 5 4 | <e> 7 6}"];
148 node4 [label = "{<b> ...}"];
155 ------------------------------------------------------------------------------
157 NOTE: Different pixel types (i.e. RGB888 and BGR888) can share the same pixel
158 size, since certain types of operations do not depend on the actual
159 arrangement of the color channels in a pixel
160 (i.e. get/put pixel, rotate buffer 90 degrees, etc.).
162 TODO: Rename size to bpp?
168 -------------------------------------------------------------------------------
169 class PixelType(object):
171 self.chanslist = chanslist
172 self.chans = dict() # { chan_name: (offset, size) }
173 self.pixelsize = pixelsize # bits per pixel
175 def is_palette(self):
178 def is_unknown(self):
193 -------------------------------------------------------------------------------
195 This object represents pixel type which describes the sizes and arrangements of
196 channels in a pixel. Note that it carries an instance of pixel size described
200 -------------------------------------------------------------------------------
201 class PixelChannel():
202 # Index (position in pixel from left)
204 # Pixel channel name such as R, G, B, A, ...
206 # Bit offset in pixel
210 # Maximal channel value
211 self.max = 2 ** size - 1
213 -------------------------------------------------------------------------------
215 The chanslist describes pixel channel. There are some convenient members to be
216 used directly from C code whose value is a hexadecimal string, i.e. 'C_mask',
222 GFXprim uses https://github.com/metan-ucw/cct[CCT] templating engine which is
223 crafted especially for generating source code. CCT is a Python based language
224 that contains global variables with objects described in gfxprim config.
231 - Each written line is verbatim (reproduced as it is) unless it starts with
234 - Lines starting with +@\s+ are interpreted as a Python code
236 - Comments are lines starting with +@ #+
238 - Verbatim lines may also contain 'Expressions' or 'Function call'
240 - 'Expression' is a Python code that yields a value which is included in the
241 output and is enclosed between curly braces +{{ expression }}+.
243 - 'Function call' is a Python function whose output is included in the output.
244 It is called as {@ func() @}.
246 More complete documentation could be found in
247 https://github.com/metan-ucw/cct/blob/master/HOWTO[CCT howto].