blob: 290384903eafe6755236a6f66a6c2df5adf55040 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00009
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
agl@chromium.org55747cc2009-12-18 22:50:15 +0000154static uint32_t bilerptr00(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000155 return *a00;
156}
agl@chromium.org55747cc2009-12-18 22:50:15 +0000157static uint32_t bilerptr01(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000158 uint32_t c00 = *a00;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000159 uint32_t c01 = *a01;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000160 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}
agl@chromium.org55747cc2009-12-18 22:50:15 +0000164static uint32_t bilerptr02(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000165 uint32_t c00 = *a00;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000166 uint32_t c01 = *a01;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000167 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}
agl@chromium.org55747cc2009-12-18 22:50:15 +0000171static uint32_t bilerptr03(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000172 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
agl@chromium.org55747cc2009-12-18 22:50:15 +0000179static uint32_t bilerptr10(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000180 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}
agl@chromium.org55747cc2009-12-18 22:50:15 +0000186static uint32_t bilerptr11(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000187 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}
agl@chromium.org55747cc2009-12-18 22:50:15 +0000195static uint32_t bilerptr12(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000196 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}
agl@chromium.org55747cc2009-12-18 22:50:15 +0000204static uint32_t bilerptr13(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000205 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
agl@chromium.org55747cc2009-12-18 22:50:15 +0000214static uint32_t bilerptr20(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000215 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}
agl@chromium.org55747cc2009-12-18 22:50:15 +0000221static uint32_t bilerptr21(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000222 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}
agl@chromium.org55747cc2009-12-18 22:50:15 +0000230static uint32_t bilerptr22(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000231 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}
agl@chromium.org55747cc2009-12-18 22:50:15 +0000239static uint32_t bilerptr23(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000240 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
agl@chromium.org55747cc2009-12-18 22:50:15 +0000249static uint32_t bilerptr30(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000250 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}
agl@chromium.org55747cc2009-12-18 22:50:15 +0000256static uint32_t bilerptr31(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000257 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}
agl@chromium.org55747cc2009-12-18 22:50:15 +0000265static uint32_t bilerptr32(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000266 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}
agl@chromium.org55747cc2009-12-18 22:50:15 +0000274static uint32_t bilerptr33(const uint32_t* a00, const uint32_t* a01, const uint32_t* a10, const uint32_t* a11) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000275 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}