|
1 /* WARNING: This file is generated by combine.pl from combine.inc. |
|
2 Please edit one of those files rather than this one. */ |
|
3 |
|
4 #line 1 "pixman-combine.c.template" |
|
5 |
|
6 #define COMPONENT_SIZE 16 |
|
7 #define MASK 0xffffULL |
|
8 #define ONE_HALF 0x8000ULL |
|
9 |
|
10 #define A_SHIFT 16 * 3 |
|
11 #define R_SHIFT 16 * 2 |
|
12 #define G_SHIFT 16 |
|
13 #define A_MASK 0xffff000000000000ULL |
|
14 #define R_MASK 0xffff00000000ULL |
|
15 #define G_MASK 0xffff0000ULL |
|
16 |
|
17 #define RB_MASK 0xffff0000ffffULL |
|
18 #define AG_MASK 0xffff0000ffff0000ULL |
|
19 #define RB_ONE_HALF 0x800000008000ULL |
|
20 #define RB_MASK_PLUS_ONE 0x10000000010000ULL |
|
21 |
|
22 #define ALPHA_16(x) ((x) >> A_SHIFT) |
|
23 #define RED_16(x) (((x) >> R_SHIFT) & MASK) |
|
24 #define GREEN_16(x) (((x) >> G_SHIFT) & MASK) |
|
25 #define BLUE_16(x) ((x) & MASK) |
|
26 |
|
27 /* |
|
28 * Helper macros. |
|
29 */ |
|
30 |
|
31 #define MUL_UN16(a, b, t) \ |
|
32 ((t) = (a) * (uint32_t)(b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT )) |
|
33 |
|
34 #define DIV_UN16(a, b) \ |
|
35 (((uint32_t) (a) * MASK + ((b) / 2)) / (b)) |
|
36 |
|
37 #define ADD_UN16(x, y, t) \ |
|
38 ((t) = (x) + (y), \ |
|
39 (uint64_t) (uint16_t) ((t) | (0 - ((t) >> G_SHIFT)))) |
|
40 |
|
41 #define DIV_ONE_UN16(x) \ |
|
42 (((x) + ONE_HALF + (((x) + ONE_HALF) >> G_SHIFT)) >> G_SHIFT) |
|
43 |
|
44 /* |
|
45 * The methods below use some tricks to be able to do two color |
|
46 * components at the same time. |
|
47 */ |
|
48 |
|
49 /* |
|
50 * x_rb = (x_rb * a) / 255 |
|
51 */ |
|
52 #define UN16_rb_MUL_UN16(x, a, t) \ |
|
53 do \ |
|
54 { \ |
|
55 t = ((x) & RB_MASK) * (a); \ |
|
56 t += RB_ONE_HALF; \ |
|
57 x = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \ |
|
58 x &= RB_MASK; \ |
|
59 } while (0) |
|
60 |
|
61 /* |
|
62 * x_rb = min (x_rb + y_rb, 255) |
|
63 */ |
|
64 #define UN16_rb_ADD_UN16_rb(x, y, t) \ |
|
65 do \ |
|
66 { \ |
|
67 t = ((x) + (y)); \ |
|
68 t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); \ |
|
69 x = (t & RB_MASK); \ |
|
70 } while (0) |
|
71 |
|
72 /* |
|
73 * x_rb = (x_rb * a_rb) / 255 |
|
74 */ |
|
75 #define UN16_rb_MUL_UN16_rb(x, a, t) \ |
|
76 do \ |
|
77 { \ |
|
78 t = (x & MASK) * (a & MASK); \ |
|
79 t |= (x & R_MASK) * ((a >> R_SHIFT) & MASK); \ |
|
80 t += RB_ONE_HALF; \ |
|
81 t = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \ |
|
82 x = t & RB_MASK; \ |
|
83 } while (0) |
|
84 |
|
85 /* |
|
86 * x_c = (x_c * a) / 255 |
|
87 */ |
|
88 #define UN16x4_MUL_UN16(x, a) \ |
|
89 do \ |
|
90 { \ |
|
91 uint64_t r1__, r2__, t__; \ |
|
92 \ |
|
93 r1__ = (x); \ |
|
94 UN16_rb_MUL_UN16 (r1__, (a), t__); \ |
|
95 \ |
|
96 r2__ = (x) >> G_SHIFT; \ |
|
97 UN16_rb_MUL_UN16 (r2__, (a), t__); \ |
|
98 \ |
|
99 (x) = r1__ | (r2__ << G_SHIFT); \ |
|
100 } while (0) |
|
101 |
|
102 /* |
|
103 * x_c = (x_c * a) / 255 + y_c |
|
104 */ |
|
105 #define UN16x4_MUL_UN16_ADD_UN16x4(x, a, y) \ |
|
106 do \ |
|
107 { \ |
|
108 uint64_t r1__, r2__, r3__, t__; \ |
|
109 \ |
|
110 r1__ = (x); \ |
|
111 r2__ = (y) & RB_MASK; \ |
|
112 UN16_rb_MUL_UN16 (r1__, (a), t__); \ |
|
113 UN16_rb_ADD_UN16_rb (r1__, r2__, t__); \ |
|
114 \ |
|
115 r2__ = (x) >> G_SHIFT; \ |
|
116 r3__ = ((y) >> G_SHIFT) & RB_MASK; \ |
|
117 UN16_rb_MUL_UN16 (r2__, (a), t__); \ |
|
118 UN16_rb_ADD_UN16_rb (r2__, r3__, t__); \ |
|
119 \ |
|
120 (x) = r1__ | (r2__ << G_SHIFT); \ |
|
121 } while (0) |
|
122 |
|
123 /* |
|
124 * x_c = (x_c * a + y_c * b) / 255 |
|
125 */ |
|
126 #define UN16x4_MUL_UN16_ADD_UN16x4_MUL_UN16(x, a, y, b) \ |
|
127 do \ |
|
128 { \ |
|
129 uint64_t r1__, r2__, r3__, t__; \ |
|
130 \ |
|
131 r1__ = (x); \ |
|
132 r2__ = (y); \ |
|
133 UN16_rb_MUL_UN16 (r1__, (a), t__); \ |
|
134 UN16_rb_MUL_UN16 (r2__, (b), t__); \ |
|
135 UN16_rb_ADD_UN16_rb (r1__, r2__, t__); \ |
|
136 \ |
|
137 r2__ = ((x) >> G_SHIFT); \ |
|
138 r3__ = ((y) >> G_SHIFT); \ |
|
139 UN16_rb_MUL_UN16 (r2__, (a), t__); \ |
|
140 UN16_rb_MUL_UN16 (r3__, (b), t__); \ |
|
141 UN16_rb_ADD_UN16_rb (r2__, r3__, t__); \ |
|
142 \ |
|
143 (x) = r1__ | (r2__ << G_SHIFT); \ |
|
144 } while (0) |
|
145 |
|
146 /* |
|
147 * x_c = (x_c * a_c) / 255 |
|
148 */ |
|
149 #define UN16x4_MUL_UN16x4(x, a) \ |
|
150 do \ |
|
151 { \ |
|
152 uint64_t r1__, r2__, r3__, t__; \ |
|
153 \ |
|
154 r1__ = (x); \ |
|
155 r2__ = (a); \ |
|
156 UN16_rb_MUL_UN16_rb (r1__, r2__, t__); \ |
|
157 \ |
|
158 r2__ = (x) >> G_SHIFT; \ |
|
159 r3__ = (a) >> G_SHIFT; \ |
|
160 UN16_rb_MUL_UN16_rb (r2__, r3__, t__); \ |
|
161 \ |
|
162 (x) = r1__ | (r2__ << G_SHIFT); \ |
|
163 } while (0) |
|
164 |
|
165 /* |
|
166 * x_c = (x_c * a_c) / 255 + y_c |
|
167 */ |
|
168 #define UN16x4_MUL_UN16x4_ADD_UN16x4(x, a, y) \ |
|
169 do \ |
|
170 { \ |
|
171 uint64_t r1__, r2__, r3__, t__; \ |
|
172 \ |
|
173 r1__ = (x); \ |
|
174 r2__ = (a); \ |
|
175 UN16_rb_MUL_UN16_rb (r1__, r2__, t__); \ |
|
176 r2__ = (y) & RB_MASK; \ |
|
177 UN16_rb_ADD_UN16_rb (r1__, r2__, t__); \ |
|
178 \ |
|
179 r2__ = ((x) >> G_SHIFT); \ |
|
180 r3__ = ((a) >> G_SHIFT); \ |
|
181 UN16_rb_MUL_UN16_rb (r2__, r3__, t__); \ |
|
182 r3__ = ((y) >> G_SHIFT) & RB_MASK; \ |
|
183 UN16_rb_ADD_UN16_rb (r2__, r3__, t__); \ |
|
184 \ |
|
185 (x) = r1__ | (r2__ << G_SHIFT); \ |
|
186 } while (0) |
|
187 |
|
188 /* |
|
189 * x_c = (x_c * a_c + y_c * b) / 255 |
|
190 */ |
|
191 #define UN16x4_MUL_UN16x4_ADD_UN16x4_MUL_UN16(x, a, y, b) \ |
|
192 do \ |
|
193 { \ |
|
194 uint64_t r1__, r2__, r3__, t__; \ |
|
195 \ |
|
196 r1__ = (x); \ |
|
197 r2__ = (a); \ |
|
198 UN16_rb_MUL_UN16_rb (r1__, r2__, t__); \ |
|
199 r2__ = (y); \ |
|
200 UN16_rb_MUL_UN16 (r2__, (b), t__); \ |
|
201 UN16_rb_ADD_UN16_rb (r1__, r2__, t__); \ |
|
202 \ |
|
203 r2__ = (x) >> G_SHIFT; \ |
|
204 r3__ = (a) >> G_SHIFT; \ |
|
205 UN16_rb_MUL_UN16_rb (r2__, r3__, t__); \ |
|
206 r3__ = (y) >> G_SHIFT; \ |
|
207 UN16_rb_MUL_UN16 (r3__, (b), t__); \ |
|
208 UN16_rb_ADD_UN16_rb (r2__, r3__, t__); \ |
|
209 \ |
|
210 x = r1__ | (r2__ << G_SHIFT); \ |
|
211 } while (0) |
|
212 |
|
213 /* |
|
214 x_c = min(x_c + y_c, 255) |
|
215 */ |
|
216 #define UN16x4_ADD_UN16x4(x, y) \ |
|
217 do \ |
|
218 { \ |
|
219 uint64_t r1__, r2__, r3__, t__; \ |
|
220 \ |
|
221 r1__ = (x) & RB_MASK; \ |
|
222 r2__ = (y) & RB_MASK; \ |
|
223 UN16_rb_ADD_UN16_rb (r1__, r2__, t__); \ |
|
224 \ |
|
225 r2__ = ((x) >> G_SHIFT) & RB_MASK; \ |
|
226 r3__ = ((y) >> G_SHIFT) & RB_MASK; \ |
|
227 UN16_rb_ADD_UN16_rb (r2__, r3__, t__); \ |
|
228 \ |
|
229 x = r1__ | (r2__ << G_SHIFT); \ |
|
230 } while (0) |