16 #define RB_MASK_PLUS_ONE
18 #define ALPHA_c(x) ((x) >> A_SHIFT)
19 #define RED_c(x) (((x) >> R_SHIFT) & MASK)
20 #define GREEN_c(x) (((x) >> G_SHIFT) & MASK)
21 #define BLUE_c(x) ((x) & MASK)
27 #define MUL_UNc(a,b,t) ( (t) = (a) * (b) + ONE_HALF, ( ( ( (t)>>G_SHIFT ) + (t) )>>G_SHIFT ) )
28 #define DIV_UNc(a,b) (((comp2_t) (a) * MASK) / (b))
29 #define ADD_UNc(x,y,t) ( \
31 (comp4_t) (comp1_t) ((t) | (0 - ((t) >> G_SHIFT))))
33 #define DIV_ONE_UNc(x) (((x) + ONE_HALF + (((x) + ONE_HALF) >> G_SHIFT)) >> G_SHIFT)
36 The methods below use some tricks to be able to do two color
37 components at the same time.
43 #define UNcx4_MUL_UNc(x, a) do { \
44 comp4_t t = ((x & RB_MASK) * a) + RB_ONE_HALF; \
45 t = (t + ((t >> COMPONENT_SIZE) & RB_MASK)) >> COMPONENT_SIZE; \
48 x = (((x >> COMPONENT_SIZE) & RB_MASK) * a) + RB_ONE_HALF; \
49 x = (x + ((x >> COMPONENT_SIZE) & RB_MASK)); \
50 x &= RB_MASK << COMPONENT_SIZE; \
55 x_c = (x_c * a) / 255 + y_c
57 #define UNcx4_MUL_UNc_ADD_UNcx4(x, a, y) do { \
58 /* multiply and divide: trunc((i + 128)*257/65536) */ \
59 comp4_t t = ((x & RB_MASK) * a) + RB_ONE_HALF; \
60 t = (t + ((t >> COMPONENT_SIZE) & RB_MASK)) >> COMPONENT_SIZE; \
67 t |= RB_MASK_PLUS_ONE - ((t >> COMPONENT_SIZE) & RB_MASK); \
70 /* multiply and divide */ \
71 x = (((x >> COMPONENT_SIZE) & RB_MASK) * a) + RB_ONE_HALF; \
72 x = (x + ((x >> COMPONENT_SIZE) & RB_MASK)) >> COMPONENT_SIZE; \
76 x += (y >> COMPONENT_SIZE) & RB_MASK; \
79 x |= RB_MASK_PLUS_ONE - ((x >> COMPONENT_SIZE) & RB_MASK); \
83 x <<= COMPONENT_SIZE; \
88 x_c = (x_c * a + y_c * b) / 255
90 #define UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc(x, a, y, b) do { \
92 comp4_t r = (x >> A_SHIFT) * a + (y >> A_SHIFT) * b + ONE_HALF; \
93 r += (r >> G_SHIFT); \
96 t = (x & G_MASK) * a + (y & G_MASK) * b; \
97 t += (t >> G_SHIFT) + (ONE_HALF << G_SHIFT); \
101 t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); \
105 r = ((x >> R_SHIFT) & MASK) * a + \
106 ((y >> R_SHIFT) & MASK) * b + ONE_HALF; \
107 r += (r >> G_SHIFT); \
110 x = (x & MASK) * a + (y & MASK) * b + ONE_HALF; \
111 x += (x >> G_SHIFT); \
114 x |= RB_MASK_PLUS_ONE - ((x >> G_SHIFT) & RB_MASK); \
120 x_c = (x_c * a_c) / 255
122 #define UNcx4_MUL_UNcx4(x, a) do { \
124 comp4_t r = (x & MASK) * (a & MASK); \
125 r |= (x & R_MASK) * ((a >> R_SHIFT) & MASK); \
127 r = (r + ((r >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \
131 t = (x & MASK) * ((a >> G_SHIFT) & MASK); \
132 t |= (x & R_MASK) * (a >> A_SHIFT); \
134 t = t + ((t >> G_SHIFT) & RB_MASK); \
135 x = r | (t & AG_MASK); \
139 x_c = (x_c * a_c) / 255 + y_c
141 #define UNcx4_MUL_UNcx4_ADD_UNcx4(x, a, y) do { \
143 comp4_t r = (x & MASK) * (a & MASK); \
144 r |= (x & R_MASK) * ((a >> R_SHIFT) & MASK); \
146 r = (r + ((r >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \
149 r |= RB_MASK_PLUS_ONE - ((r >> G_SHIFT) & RB_MASK); \
153 t = (x & MASK) * ((a >> G_SHIFT) & MASK); \
154 t |= (x & R_MASK) * (a >> A_SHIFT); \
156 t = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \
158 t += (y >> G_SHIFT) & RB_MASK; \
159 t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); \
161 x = r | (t << G_SHIFT); \
165 x_c = (x_c * a_c + y_c * b) / 255
167 #define UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc(x, a, y, b) do { \
169 comp4_t r = (x >> A_SHIFT) * (a >> A_SHIFT) + \
170 (y >> A_SHIFT) * b; \
171 r += (r >> G_SHIFT) + ONE_HALF; \
174 t = (x & G_MASK) * ((a >> G_SHIFT) & MASK) + (y & G_MASK) * b; \
175 t += (t >> G_SHIFT) + (ONE_HALF << G_SHIFT); \
179 t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); \
183 r = ((x >> R_SHIFT) & MASK) * ((a >> R_SHIFT) & MASK) + \
184 ((y >> R_SHIFT) & MASK) * b + ONE_HALF; \
185 r += (r >> G_SHIFT); \
188 x = (x & MASK) * (a & MASK) + (y & MASK) * b + ONE_HALF; \
189 x += (x >> G_SHIFT); \
192 x |= RB_MASK_PLUS_ONE - ((x >> G_SHIFT) & RB_MASK); \
198 x_c = min(x_c + y_c, 255)
200 #define UNcx4_ADD_UNcx4(x, y) do { \
202 comp4_t r = (x & RB_MASK) + (y & RB_MASK); \
203 r |= RB_MASK_PLUS_ONE - ((r >> G_SHIFT) & RB_MASK); \
206 t = ((x >> G_SHIFT) & RB_MASK) + ((y >> G_SHIFT) & RB_MASK); \
207 t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); \
208 r |= (t & RB_MASK) << G_SHIFT; \