Add support for extended blend mode. First pass.
[profile/ivi/pixman.git] / pixman / pixman-combine.h.template
1
2 #define COMPONENT_SIZE
3 #define MASK
4 #define ONE_HALF
5
6 #define A_SHIFT
7 #define R_SHIFT
8 #define G_SHIFT
9 #define A_MASK
10 #define R_MASK
11 #define G_MASK
12
13 #define RB_MASK
14 #define AG_MASK
15 #define RB_ONE_HALF
16 #define RB_MASK_PLUS_ONE
17
18 #define Alpha(x) ((x) >> A_SHIFT)
19
20 /*
21  * Helper macros.
22  */
23
24 #define IntMult(a,b,t) ( (t) = (a) * (b) + ONE_HALF, ( ( ( (t)>>G_SHIFT ) + (t) )>>G_SHIFT ) )
25 #define IntDiv(a,b)    (((comp2_t) (a) * MASK) / (b))
26
27 #define GetComp(v,i)   ((comp2_t) (comp1_t) ((v) >> i))
28
29 #define Add(x,y,i,t)   ((t) = GetComp(x,i) + GetComp(y,i),              \
30                         (comp4_t) ((comp1_t) ((t) | (0 - ((t) >> G_SHIFT)))) << (i))
31
32 #define DivOne(x)      (((x) + ONE_HALF + (((x) + ONE_HALF) >> G_SHIFT)) >> G_SHIFT)
33
34 /*
35   The methods below use some tricks to be able to do two color
36   components at the same time.
37 */
38
39 /*
40   x_c = (x_c * a) / 255
41 */
42 #define FbByteMul(x, a) do {                                            \
43         comp4_t t = ((x & RB_MASK) * a) + RB_ONE_HALF;                  \
44         t = (t + ((t >> COMPONENT_SIZE) & RB_MASK)) >> COMPONENT_SIZE;  \
45         t &= RB_MASK;                                                   \
46                                                                         \
47         x = (((x >> COMPONENT_SIZE) & RB_MASK) * a) + RB_ONE_HALF;      \
48         x = (x + ((x >> COMPONENT_SIZE) & RB_MASK));                    \
49         x &= RB_MASK << COMPONENT_SIZE;                                 \
50         x += t;                                                         \
51     } while (0)
52
53 /*
54   x_c = (x_c * a) / 255 + y
55 */
56 #define FbByteMulAdd(x, a, y) do {                                      \
57         /* multiply and divide: trunc((i + 128)*257/65536) */           \
58         comp4_t t = ((x & RB_MASK) * a) + RB_ONE_HALF;                  \
59         t = (t + ((t >> COMPONENT_SIZE) & RB_MASK)) >> COMPONENT_SIZE;  \
60         t &= RB_MASK;                                                   \
61                                                                         \
62         /* add */                                                       \
63         t += y & RB_MASK;                                               \
64                                                                         \
65         /* saturate */                                                  \
66         t |= RB_MASK_PLUS_ONE - ((t >> COMPONENT_SIZE) & RB_MASK);      \
67         t &= RB_MASK;                                                   \
68                                                                         \
69         /* multiply and divide */                                       \
70         x = (((x >> COMPONENT_SIZE) & RB_MASK) * a) + RB_ONE_HALF;      \
71         x = (x + ((x >> COMPONENT_SIZE) & RB_MASK)) >> COMPONENT_SIZE;  \
72         x &= RB_MASK;                                                   \
73                                                                         \
74         /* add */                                                       \
75         x += (y >> COMPONENT_SIZE) & RB_MASK;                           \
76                                                                         \
77         /* saturate */                                                  \
78         x |= RB_MASK_PLUS_ONE - ((x >> COMPONENT_SIZE) & RB_MASK);      \
79         x &= RB_MASK;                                                   \
80                                                                         \
81         /* recombine */                                                 \
82         x <<= COMPONENT_SIZE;                                           \
83         x += t;                                                         \
84     } while (0)
85
86 /*
87   x_c = (x_c * a + y_c * b) / 255
88 */
89 #define FbByteAddMul(x, a, y, b) do {                                   \
90         comp4_t t;                                                      \
91         comp4_t r = (x >> A_SHIFT) * a + (y >> A_SHIFT) * b + ONE_HALF; \
92         r += (r >> G_SHIFT);                                            \
93         r >>= G_SHIFT;                                                  \
94                                                                         \
95         t = (x & G_MASK) * a + (y & G_MASK) * b;                        \
96         t += (t >> G_SHIFT) + (ONE_HALF << G_SHIFT);                    \
97         t >>= R_SHIFT;                                                  \
98                                                                         \
99         t |= r << R_SHIFT;                                              \
100         t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK);             \
101         t &= RB_MASK;                                                   \
102         t <<= G_SHIFT;                                                  \
103                                                                         \
104         r = ((x >> R_SHIFT) & MASK) * a +                               \
105             ((y >> R_SHIFT) & MASK) * b + ONE_HALF;                     \
106         r += (r >> G_SHIFT);                                            \
107         r >>= G_SHIFT;                                                  \
108                                                                         \
109         x = (x & MASK) * a + (y & MASK) * b + ONE_HALF;                 \
110         x += (x >> G_SHIFT);                                            \
111         x >>= G_SHIFT;                                                  \
112         x |= r << R_SHIFT;                                              \
113         x |= RB_MASK_PLUS_ONE - ((x >> G_SHIFT) & RB_MASK);             \
114         x &= RB_MASK;                                                   \
115         x |= t;                                                         \
116     } while (0)
117
118 /*
119   x_c = (x_c * a_c) / 255
120 */
121 #define FbByteMulC(x, a) do {                                           \
122         comp4_t t;                                                      \
123         comp4_t r = (x & MASK) * (a & MASK);                            \
124         r |= (x & R_MASK) * ((a >> R_SHIFT) & MASK);                    \
125         r += RB_ONE_HALF;                                               \
126         r = (r + ((r >> G_SHIFT) & RB_MASK)) >> G_SHIFT;                \
127         r &= RB_MASK;                                                   \
128                                                                         \
129         x >>= G_SHIFT;                                                  \
130         t = (x & MASK) * ((a >> G_SHIFT) & MASK);                       \
131         t |= (x & R_MASK) * (a >> A_SHIFT);                             \
132         t += RB_ONE_HALF;                                               \
133         t = t + ((t >> G_SHIFT) & RB_MASK);                             \
134         x = r | (t & AG_MASK);                                          \
135     } while (0)
136
137 /*
138   x_c = (x_c * a) / 255 + y
139 */
140 #define FbByteMulAddC(x, a, y) do {                                     \
141         comp4_t t;                                                      \
142         comp4_t r = (x & MASK) * (a & MASK);                            \
143         r |= (x & R_MASK) * ((a >> R_SHIFT) & MASK);                    \
144         r += RB_ONE_HALF;                                               \
145         r = (r + ((r >> G_SHIFT) & RB_MASK)) >> G_SHIFT;                \
146         r &= RB_MASK;                                                   \
147         r += y & RB_MASK;                                               \
148         r |= RB_MASK_PLUS_ONE - ((r >> G_SHIFT) & RB_MASK);             \
149         r &= RB_MASK;                                                   \
150                                                                         \
151         x >>= G_SHIFT;                                                  \
152         t = (x & MASK) * ((a >> G_SHIFT) & MASK);                       \
153         t |= (x & R_MASK) * (a >> A_SHIFT);                             \
154         t += RB_ONE_HALF;                                               \
155         t = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT;                \
156         t &= RB_MASK;                                                   \
157         t += (y >> G_SHIFT) & RB_MASK;                                  \
158         t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK);             \
159         t &= RB_MASK;                                                   \
160         x = r | (t << G_SHIFT);                                         \
161     } while (0)
162
163 /*
164   x_c = (x_c * a_c + y_c * b) / 255
165 */
166 #define FbByteAddMulC(x, a, y, b) do {                                  \
167         comp4_t t;                                                      \
168         comp4_t r = (x >> A_SHIFT) * (a >> A_SHIFT) +                   \
169                      (y >> A_SHIFT) * b;                                \
170         r += (r >> G_SHIFT) + ONE_HALF;                                 \
171         r >>= G_SHIFT;                                                  \
172                                                                         \
173         t = (x & G_MASK) * ((a >> G_SHIFT) & MASK) + (y & G_MASK) * b;  \
174         t += (t >> G_SHIFT) + (ONE_HALF << G_SHIFT);                    \
175         t >>= R_SHIFT;                                                  \
176                                                                         \
177         t |= r << R_SHIFT;                                              \
178         t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK);             \
179         t &= RB_MASK;                                                   \
180         t <<= G_SHIFT;                                                  \
181                                                                         \
182         r = ((x >> R_SHIFT) & MASK) * ((a >> R_SHIFT) & MASK) +         \
183             ((y >> R_SHIFT) & MASK) * b + ONE_HALF;                     \
184         r += (r >> G_SHIFT);                                            \
185         r >>= G_SHIFT;                                                  \
186                                                                         \
187         x = (x & MASK) * (a & MASK) + (y & MASK) * b + ONE_HALF;        \
188         x += (x >> G_SHIFT);                                            \
189         x >>= G_SHIFT;                                                  \
190         x |= r << R_SHIFT;                                              \
191         x |= RB_MASK_PLUS_ONE - ((x >> G_SHIFT) & RB_MASK);             \
192         x &= RB_MASK;                                                   \
193         x |= t;                                                         \
194     } while (0)
195
196 /*
197   x_c = min(x_c + y_c, 255)
198 */
199 #define FbByteAdd(x, y) do {                                            \
200         comp4_t t;                                                      \
201         comp4_t r = (x & RB_MASK) + (y & RB_MASK);                      \
202         r |= RB_MASK_PLUS_ONE - ((r >> G_SHIFT) & RB_MASK);             \
203         r &= RB_MASK;                                                   \
204                                                                         \
205         t = ((x >> G_SHIFT) & RB_MASK) + ((y >> G_SHIFT) & RB_MASK);    \
206         t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK);             \
207         r |= (t & RB_MASK) << G_SHIFT;                                  \
208         x = r;                                                          \
209     } while (0)
210