1 2 /* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #include "SkFilterProc.h" 11 12 /* [1-x 1-y] [x 1-y] 13 [1-x y] [x y] 14 */ 15 16 static unsigned bilerp00(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return a00; } 17 static unsigned bilerp01(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (3 * a00 + a01) >> 2; } 18 static unsigned bilerp02(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (a00 + a01) >> 1; } 19 static unsigned bilerp03(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (a00 + 3 * a01) >> 2; } 20 21 static unsigned bilerp10(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (3 * a00 + a10) >> 2; } 22 static unsigned bilerp11(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (9 * a00 + 3 * (a01 + a10) + a11) >> 4; } 23 static unsigned bilerp12(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (3 * (a00 + a01) + a10 + a11) >> 3; } 24 static unsigned bilerp13(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (9 * a01 + 3 * (a00 + a11) + a10) >> 4; } 25 26 static unsigned bilerp20(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (a00 + a10) >> 1; } 27 static unsigned bilerp21(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (3 * (a00 + a10) + a01 + a11) >> 3; } 28 static unsigned bilerp22(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (a00 + a01 + a10 + a11) >> 2; } 29 static unsigned bilerp23(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (3 * (a01 + a11) + a00 + a10) >> 3; } 30 31 static unsigned bilerp30(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (a00 + 3 * a10) >> 2; } 32 static unsigned bilerp31(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (9 * a10 + 3 * (a00 + a11) + a01) >> 4; } 33 static unsigned bilerp32(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (3 * (a10 + a11) + a00 + a01) >> 3; } 34 static unsigned bilerp33(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (9 * a11 + 3 * (a01 + a10) + a00) >> 4; } 35 36 static const SkFilterProc gBilerpProcs[4 * 4] = { 37 bilerp00, bilerp01, bilerp02, bilerp03, 38 bilerp10, bilerp11, bilerp12, bilerp13, 39 bilerp20, bilerp21, bilerp22, bilerp23, 40 bilerp30, bilerp31, bilerp32, bilerp33 41 }; 42 43 const SkFilterProc* SkGetBilinearFilterProcTable() 44 { 45 return gBilerpProcs; 46 } 47 48 /////////////////////////////////////////////////////////////////////////////// 49 /////////////////////////////////////////////////////////////////////////////// 50 51 #define MASK 0xFF00FF 52 #define LO_PAIR(x) ((x) & MASK) 53 #define HI_PAIR(x) (((x) >> 8) & MASK) 54 #define COMBINE(lo, hi) (((lo) & ~0xFF00) | (((hi) & ~0xFF00) << 8)) 55 56 /////////////////////////////////////////////////////////////////////////////// 57 58 static unsigned bilerp4_00(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 59 return c00; 60 } 61 static unsigned bilerp4_01(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 62 uint32_t lo = (3 * LO_PAIR(c00) + LO_PAIR(c01)) >> 2; 63 uint32_t hi = (3 * HI_PAIR(c00) + HI_PAIR(c01)) >> 2; 64 return COMBINE(lo, hi); 65 } 66 static unsigned bilerp4_02(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 67 uint32_t lo = (LO_PAIR(c00) + LO_PAIR(c01)) >> 1; 68 uint32_t hi = (HI_PAIR(c00) + HI_PAIR(c01)) >> 1; 69 return COMBINE(lo, hi); 70 } 71 static unsigned bilerp4_03(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 72 uint32_t lo = (LO_PAIR(c00) + 3 * LO_PAIR(c01)) >> 2; 73 uint32_t hi = (HI_PAIR(c00) + 3 * HI_PAIR(c01)) >> 2; 74 return COMBINE(lo, hi); 75 } 76 77 static unsigned bilerp4_10(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 78 uint32_t lo = (3 * LO_PAIR(c00) + LO_PAIR(c10)) >> 2; 79 uint32_t hi = (3 * HI_PAIR(c00) + HI_PAIR(c10)) >> 2; 80 return COMBINE(lo, hi); 81 } 82 static unsigned bilerp4_11(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 83 uint32_t lo = (9 * LO_PAIR(c00) + 3 * (LO_PAIR(c01) + LO_PAIR(c10)) + LO_PAIR(c11)) >> 4; 84 uint32_t hi = (9 * HI_PAIR(c00) + 3 * (HI_PAIR(c01) + HI_PAIR(c10)) + HI_PAIR(c11)) >> 4; 85 return COMBINE(lo, hi); 86 } 87 static unsigned bilerp4_12(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 88 uint32_t lo = (3 * (LO_PAIR(c00) + LO_PAIR(c01)) + LO_PAIR(c10) + LO_PAIR(c11)) >> 3; 89 uint32_t hi = (3 * (HI_PAIR(c00) + HI_PAIR(c01)) + HI_PAIR(c10) + HI_PAIR(c11)) >> 3; 90 return COMBINE(lo, hi); 91 } 92 static unsigned bilerp4_13(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 93 uint32_t lo = (9 * LO_PAIR(c01) + 3 * (LO_PAIR(c00) + LO_PAIR(c11)) + LO_PAIR(c10)) >> 4; 94 uint32_t hi = (9 * HI_PAIR(c01) + 3 * (HI_PAIR(c00) + HI_PAIR(c11)) + HI_PAIR(c10)) >> 4; 95 return COMBINE(lo, hi); 96 } 97 98 static unsigned bilerp4_20(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 99 uint32_t lo = (LO_PAIR(c00) + LO_PAIR(c10)) >> 1; 100 uint32_t hi = (HI_PAIR(c00) + HI_PAIR(c10)) >> 1; 101 return COMBINE(lo, hi); 102 } 103 static unsigned bilerp4_21(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 104 uint32_t lo = (3 * (LO_PAIR(c00) + LO_PAIR(c10)) + LO_PAIR(c01) + LO_PAIR(c11)) >> 3; 105 uint32_t hi = (3 * (HI_PAIR(c00) + HI_PAIR(c10)) + HI_PAIR(c01) + HI_PAIR(c11)) >> 3; 106 return COMBINE(lo, hi); 107 } 108 static unsigned bilerp4_22(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 109 uint32_t lo = (LO_PAIR(c00) + LO_PAIR(c01) + LO_PAIR(c10) + LO_PAIR(c11)) >> 2; 110 uint32_t hi = (HI_PAIR(c00) + HI_PAIR(c01) + HI_PAIR(c10) + HI_PAIR(c11)) >> 2; 111 return COMBINE(lo, hi); 112 } 113 static unsigned bilerp4_23(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 114 uint32_t lo = (3 * (LO_PAIR(c01) + LO_PAIR(c11)) + LO_PAIR(c00) + LO_PAIR(c10)) >> 3; 115 uint32_t hi = (3 * (HI_PAIR(c01) + HI_PAIR(c11)) + HI_PAIR(c00) + HI_PAIR(c10)) >> 3; 116 return COMBINE(lo, hi); 117 } 118 119 static unsigned bilerp4_30(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 120 uint32_t lo = (LO_PAIR(c00) + 3 * LO_PAIR(c10)) >> 2; 121 uint32_t hi = (HI_PAIR(c00) + 3 * HI_PAIR(c10)) >> 2; 122 return COMBINE(lo, hi); 123 } 124 static unsigned bilerp4_31(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 125 uint32_t lo = (9 * LO_PAIR(c10) + 3 * (LO_PAIR(c00) + LO_PAIR(c11)) + LO_PAIR(c01)) >> 4; 126 uint32_t hi = (9 * HI_PAIR(c10) + 3 * (HI_PAIR(c00) + HI_PAIR(c11)) + HI_PAIR(c01)) >> 4; 127 return COMBINE(lo, hi); 128 } 129 static unsigned bilerp4_32(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 130 uint32_t lo = (3 * (LO_PAIR(c10) + LO_PAIR(c11)) + LO_PAIR(c00) + LO_PAIR(c01)) >> 3; 131 uint32_t hi = (3 * (HI_PAIR(c10) + HI_PAIR(c11)) + HI_PAIR(c00) + HI_PAIR(c01)) >> 3; 132 return COMBINE(lo, hi); 133 } 134 static unsigned bilerp4_33(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 135 uint32_t lo = (9 * LO_PAIR(c11) + 3 * (LO_PAIR(c01) + LO_PAIR(c10)) + LO_PAIR(c00)) >> 4; 136 uint32_t hi = (9 * HI_PAIR(c11) + 3 * (HI_PAIR(c01) + HI_PAIR(c10)) + HI_PAIR(c00)) >> 4; 137 return COMBINE(lo, hi); 138 } 139 140 static const SkFilter32Proc gBilerp32Procs[4 * 4] = { 141 bilerp4_00, bilerp4_01, bilerp4_02, bilerp4_03, 142 bilerp4_10, bilerp4_11, bilerp4_12, bilerp4_13, 143 bilerp4_20, bilerp4_21, bilerp4_22, bilerp4_23, 144 bilerp4_30, bilerp4_31, bilerp4_32, bilerp4_33 145 }; 146 147 const SkFilter32Proc* SkGetFilter32ProcTable() 148 { 149 return gBilerp32Procs; 150 } 151 152 /////////////////////////////////////////////////////////////////////////////// 153 154 static uint32_t bilerptr00(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 155 return *a00; 156 } 157 static uint32_t bilerptr01(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 158 uint32_t c00 = *a00; 159 uint32_t c01 = *a01; 160 uint32_t lo = (3 * LO_PAIR(c00) + LO_PAIR(c01)) >> 2; 161 uint32_t hi = (3 * HI_PAIR(c00) + HI_PAIR(c01)) >> 2; 162 return COMBINE(lo, hi); 163 } 164 static uint32_t bilerptr02(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 165 uint32_t c00 = *a00; 166 uint32_t c01 = *a01; 167 uint32_t lo = (LO_PAIR(c00) + LO_PAIR(c01)) >> 1; 168 uint32_t hi = (HI_PAIR(c00) + HI_PAIR(c01)) >> 1; 169 return COMBINE(lo, hi); 170 } 171 static uint32_t bilerptr03(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 172 uint32_t c00 = *a00; 173 uint32_t c01 = *a01; 174 uint32_t lo = (LO_PAIR(c00) + 3 * LO_PAIR(c01)) >> 2; 175 uint32_t hi = (HI_PAIR(c00) + 3 * HI_PAIR(c01)) >> 2; 176 return COMBINE(lo, hi); 177 } 178 179 static uint32_t bilerptr10(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 180 uint32_t c00 = *a00; 181 uint32_t c10 = *a10; 182 uint32_t lo = (3 * LO_PAIR(c00) + LO_PAIR(c10)) >> 2; 183 uint32_t hi = (3 * HI_PAIR(c00) + HI_PAIR(c10)) >> 2; 184 return COMBINE(lo, hi); 185 } 186 static uint32_t bilerptr11(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 187 uint32_t c00 = *a00; 188 uint32_t c01 = *a01; 189 uint32_t c10 = *a10; 190 uint32_t c11 = *a11; 191 uint32_t lo = (9 * LO_PAIR(c00) + 3 * (LO_PAIR(c01) + LO_PAIR(c10)) + LO_PAIR(c11)) >> 4; 192 uint32_t hi = (9 * HI_PAIR(c00) + 3 * (HI_PAIR(c01) + HI_PAIR(c10)) + HI_PAIR(c11)) >> 4; 193 return COMBINE(lo, hi); 194 } 195 static uint32_t bilerptr12(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 196 uint32_t c00 = *a00; 197 uint32_t c01 = *a01; 198 uint32_t c10 = *a10; 199 uint32_t c11 = *a11; 200 uint32_t lo = (3 * (LO_PAIR(c00) + LO_PAIR(c01)) + LO_PAIR(c10) + LO_PAIR(c11)) >> 3; 201 uint32_t hi = (3 * (HI_PAIR(c00) + HI_PAIR(c01)) + HI_PAIR(c10) + HI_PAIR(c11)) >> 3; 202 return COMBINE(lo, hi); 203 } 204 static uint32_t bilerptr13(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 205 uint32_t c00 = *a00; 206 uint32_t c01 = *a01; 207 uint32_t c10 = *a10; 208 uint32_t c11 = *a11; 209 uint32_t lo = (9 * LO_PAIR(c01) + 3 * (LO_PAIR(c00) + LO_PAIR(c11)) + LO_PAIR(c10)) >> 4; 210 uint32_t hi = (9 * HI_PAIR(c01) + 3 * (HI_PAIR(c00) + HI_PAIR(c11)) + HI_PAIR(c10)) >> 4; 211 return COMBINE(lo, hi); 212 } 213 214 static uint32_t bilerptr20(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 215 uint32_t c00 = *a00; 216 uint32_t c10 = *a10; 217 uint32_t lo = (LO_PAIR(c00) + LO_PAIR(c10)) >> 1; 218 uint32_t hi = (HI_PAIR(c00) + HI_PAIR(c10)) >> 1; 219 return COMBINE(lo, hi); 220 } 221 static uint32_t bilerptr21(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 222 uint32_t c00 = *a00; 223 uint32_t c01 = *a01; 224 uint32_t c10 = *a10; 225 uint32_t c11 = *a11; 226 uint32_t lo = (3 * (LO_PAIR(c00) + LO_PAIR(c10)) + LO_PAIR(c01) + LO_PAIR(c11)) >> 3; 227 uint32_t hi = (3 * (HI_PAIR(c00) + HI_PAIR(c10)) + HI_PAIR(c01) + HI_PAIR(c11)) >> 3; 228 return COMBINE(lo, hi); 229 } 230 static uint32_t bilerptr22(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 231 uint32_t c00 = *a00; 232 uint32_t c01 = *a01; 233 uint32_t c10 = *a10; 234 uint32_t c11 = *a11; 235 uint32_t lo = (LO_PAIR(c00) + LO_PAIR(c01) + LO_PAIR(c10) + LO_PAIR(c11)) >> 2; 236 uint32_t hi = (HI_PAIR(c00) + HI_PAIR(c01) + HI_PAIR(c10) + HI_PAIR(c11)) >> 2; 237 return COMBINE(lo, hi); 238 } 239 static uint32_t bilerptr23(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 240 uint32_t c00 = *a00; 241 uint32_t c01 = *a01; 242 uint32_t c10 = *a10; 243 uint32_t c11 = *a11; 244 uint32_t lo = (3 * (LO_PAIR(c01) + LO_PAIR(c11)) + LO_PAIR(c00) + LO_PAIR(c10)) >> 3; 245 uint32_t hi = (3 * (HI_PAIR(c01) + HI_PAIR(c11)) + HI_PAIR(c00) + HI_PAIR(c10)) >> 3; 246 return COMBINE(lo, hi); 247 } 248 249 static uint32_t bilerptr30(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 250 uint32_t c00 = *a00; 251 uint32_t c10 = *a10; 252 uint32_t lo = (LO_PAIR(c00) + 3 * LO_PAIR(c10)) >> 2; 253 uint32_t hi = (HI_PAIR(c00) + 3 * HI_PAIR(c10)) >> 2; 254 return COMBINE(lo, hi); 255 } 256 static uint32_t bilerptr31(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 257 uint32_t c00 = *a00; 258 uint32_t c01 = *a01; 259 uint32_t c10 = *a10; 260 uint32_t c11 = *a11; 261 uint32_t lo = (9 * LO_PAIR(c10) + 3 * (LO_PAIR(c00) + LO_PAIR(c11)) + LO_PAIR(c01)) >> 4; 262 uint32_t hi = (9 * HI_PAIR(c10) + 3 * (HI_PAIR(c00) + HI_PAIR(c11)) + HI_PAIR(c01)) >> 4; 263 return COMBINE(lo, hi); 264 } 265 static uint32_t bilerptr32(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 266 uint32_t c00 = *a00; 267 uint32_t c01 = *a01; 268 uint32_t c10 = *a10; 269 uint32_t c11 = *a11; 270 uint32_t lo = (3 * (LO_PAIR(c10) + LO_PAIR(c11)) + LO_PAIR(c00) + LO_PAIR(c01)) >> 3; 271 uint32_t hi = (3 * (HI_PAIR(c10) + HI_PAIR(c11)) + HI_PAIR(c00) + HI_PAIR(c01)) >> 3; 272 return COMBINE(lo, hi); 273 } 274 static uint32_t bilerptr33(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 275 uint32_t c00 = *a00; 276 uint32_t c01 = *a01; 277 uint32_t c10 = *a10; 278 uint32_t c11 = *a11; 279 uint32_t lo = (9 * LO_PAIR(c11) + 3 * (LO_PAIR(c01) + LO_PAIR(c10)) + LO_PAIR(c00)) >> 4; 280 uint32_t hi = (9 * HI_PAIR(c11) + 3 * (HI_PAIR(c01) + HI_PAIR(c10)) + HI_PAIR(c00)) >> 4; 281 return COMBINE(lo, hi); 282 } 283 284 static const SkFilterPtrProc gBilerpPtrProcs[4 * 4] = { 285 bilerptr00, bilerptr01, bilerptr02, bilerptr03, 286 bilerptr10, bilerptr11, bilerptr12, bilerptr13, 287 bilerptr20, bilerptr21, bilerptr22, bilerptr23, 288 bilerptr30, bilerptr31, bilerptr32, bilerptr33 289 }; 290 291 const SkFilterPtrProc* SkGetBilinearFilterPtrProcTable() 292 { 293 return gBilerpPtrProcs; 294 } 295