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 16static unsigned bilerp00(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return a00; } 17static unsigned bilerp01(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (3 * a00 + a01) >> 2; } 18static unsigned bilerp02(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (a00 + a01) >> 1; } 19static unsigned bilerp03(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (a00 + 3 * a01) >> 2; } 20 21static unsigned bilerp10(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (3 * a00 + a10) >> 2; } 22static unsigned bilerp11(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (9 * a00 + 3 * (a01 + a10) + a11) >> 4; } 23static unsigned bilerp12(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (3 * (a00 + a01) + a10 + a11) >> 3; } 24static unsigned bilerp13(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (9 * a01 + 3 * (a00 + a11) + a10) >> 4; } 25 26static unsigned bilerp20(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (a00 + a10) >> 1; } 27static unsigned bilerp21(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (3 * (a00 + a10) + a01 + a11) >> 3; } 28static unsigned bilerp22(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (a00 + a01 + a10 + a11) >> 2; } 29static unsigned bilerp23(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (3 * (a01 + a11) + a00 + a10) >> 3; } 30 31static unsigned bilerp30(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (a00 + 3 * a10) >> 2; } 32static unsigned bilerp31(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (9 * a10 + 3 * (a00 + a11) + a01) >> 4; } 33static unsigned bilerp32(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (3 * (a10 + a11) + a00 + a01) >> 3; } 34static unsigned bilerp33(unsigned a00, unsigned a01, unsigned a10, unsigned a11) { return (9 * a11 + 3 * (a01 + a10) + a00) >> 4; } 35 36static 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 43const 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 58static unsigned bilerp4_00(uint32_t c00, uint32_t c01, uint32_t c10, uint32_t c11) { 59 return c00; 60} 61static 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} 66static 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} 71static 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 77static 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} 82static 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} 87static 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} 92static 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 98static 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} 103static 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} 108static 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} 113static 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 119static 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} 124static 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} 129static 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} 134static 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 140static 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 147const SkFilter32Proc* SkGetFilter32ProcTable() 148{ 149 return gBilerp32Procs; 150} 151 152/////////////////////////////////////////////////////////////////////////////// 153 154static uint32_t bilerptr00(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) { 155 return *a00; 156} 157static 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} 164static 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} 171static 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 179static 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} 186static 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} 195static 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} 204static 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 214static 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} 221static 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} 230static 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} 239static 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 249static 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} 256static 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} 265static 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} 274static 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 284static 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 291const SkFilterPtrProc* SkGetBilinearFilterPtrProcTable() 292{ 293 return gBilerpPtrProcs; 294} 295