Home | History | Annotate | Download | only in core
      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