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) 231