Rice GLES2 (from mupen64plus-ae) plugin. Compile but doesn't works well on the OpenPa...
[mupen64plus-pandora.git] / source / gles2rice / src / TextureFilters_hq2x.cpp
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - TextureFilters_hq2x.cpp                                 *
3  *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
4  *   Copyright (C) 2003 MaxSt ( maxst@hiend3d.com )                        *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  *   This program is distributed in the hope that it will be useful,       *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14  *   GNU General Public License for more details.                          *
15  *                                                                         *
16  *   You should have received a copy of the GNU General Public License     *
17  *   along with this program; if not, write to the                         *
18  *   Free Software Foundation, Inc.,                                       *
19  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
20  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22 #include "typedefs.h"
23
24 /************************************************************************/
25 /* hq2x filters                                                         */
26 /************************************************************************/
27
28 /***************************************************************************/
29 /* Basic types */
30
31 /***************************************************************************/
32 /* interpolation */
33
34 static unsigned interp_bits_per_pixel;
35
36 #define INTERP_16_MASK_1_3(v) ((v)&0x0F0F)
37 #define INTERP_16_MASK_SHIFT_2_4(v) (((v)&0xF0F0)>>4)
38 #define INTERP_16_MASK_SHIFTBACK_2_4(v) ((INTERP_16_MASK_1_3(v))<<4)
39
40 static inline uint16 hq2x_interp_16_521(uint16 p1, uint16 p2, uint16 p3)
41 {
42     return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*5 + INTERP_16_MASK_1_3(p2)*2 + INTERP_16_MASK_1_3(p3)*1) / 8)
43         | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*5 + INTERP_16_MASK_SHIFT_2_4(p2)*2 + INTERP_16_MASK_SHIFT_2_4(p3)*1) / 8);
44 }
45
46 static inline uint16 hq2x_interp_16_332(uint16 p1, uint16 p2, uint16 p3)
47 {
48     return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*3 + INTERP_16_MASK_1_3(p2)*3 + INTERP_16_MASK_1_3(p3)*2) / 8)
49         | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*3 + INTERP_16_MASK_SHIFT_2_4(p2)*3 + INTERP_16_MASK_SHIFT_2_4(p3)*2) / 8);
50 }
51
52 static inline uint16 hq2x_interp_16_611(uint16 p1, uint16 p2, uint16 p3)
53 {
54     return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*6 + INTERP_16_MASK_1_3(p2) + INTERP_16_MASK_1_3(p3)) / 8)
55         | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*6 + INTERP_16_MASK_SHIFT_2_4(p2) + INTERP_16_MASK_SHIFT_2_4(p3)) / 8);
56 }
57
58 static inline uint16 hq2x_interp_16_71(uint16 p1, uint16 p2)
59 {
60     return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*7 + INTERP_16_MASK_1_3(p2)) / 8)
61         | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*7 + INTERP_16_MASK_SHIFT_2_4(p2)) / 8);
62 }
63
64 static inline uint16 hq2x_interp_16_211(uint16 p1, uint16 p2, uint16 p3)
65 {
66     return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*2 + INTERP_16_MASK_1_3(p2) + INTERP_16_MASK_1_3(p3)) / 4)
67         | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*2 + INTERP_16_MASK_SHIFT_2_4(p2) + INTERP_16_MASK_SHIFT_2_4(p3)) / 4);
68 }
69
70 static inline uint16 hq2x_interp_16_772(uint16 p1, uint16 p2, uint16 p3)
71 {
72     return INTERP_16_MASK_1_3(((INTERP_16_MASK_1_3(p1) + INTERP_16_MASK_1_3(p2))*7 + INTERP_16_MASK_1_3(p3)*2) / 16)
73         | INTERP_16_MASK_SHIFTBACK_2_4(((INTERP_16_MASK_SHIFT_2_4(p1) + INTERP_16_MASK_SHIFT_2_4(p2))*7 + INTERP_16_MASK_SHIFT_2_4(p3)*2) / 16);
74 }
75
76 static inline uint16 hq2x_interp_16_11(uint16 p1, uint16 p2)
77 {
78     return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1) + INTERP_16_MASK_1_3(p2)) / 2)
79         | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1) + INTERP_16_MASK_SHIFT_2_4(p2)) / 2);
80 }
81
82 static inline uint16 hq2x_interp_16_31(uint16 p1, uint16 p2)
83 {
84     return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*3 + INTERP_16_MASK_1_3(p2)) / 4)
85         | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*3 + INTERP_16_MASK_SHIFT_2_4(p2)) / 4);
86 }
87
88 static inline uint16 hq2x_interp_16_1411(uint16 p1, uint16 p2, uint16 p3)
89 {
90     return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*14 + INTERP_16_MASK_1_3(p2) + INTERP_16_MASK_1_3(p3)) / 16)
91         | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*14 + INTERP_16_MASK_SHIFT_2_4(p2) + INTERP_16_MASK_SHIFT_2_4(p3)) / 16);
92 }
93
94 static inline uint16 hq2x_interp_16_431(uint16 p1, uint16 p2, uint16 p3)
95 {
96     return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*4 + INTERP_16_MASK_1_3(p2)*3 + INTERP_16_MASK_1_3(p3)) / 8)
97         | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*4 + INTERP_16_MASK_SHIFT_2_4(p2)*3 + INTERP_16_MASK_SHIFT_2_4(p3)) / 8);
98 }
99
100 static inline uint16 hq2x_interp_16_53(uint16 p1, uint16 p2)
101 {
102     return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*5 + INTERP_16_MASK_1_3(p2)*3) / 8)
103         | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*5 + INTERP_16_MASK_SHIFT_2_4(p2)*3) / 8);
104 }
105
106 static inline uint16 hq2x_interp_16_151(uint16 p1, uint16 p2)
107 {
108     return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*15 + INTERP_16_MASK_1_3(p2)) / 16)
109         | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*15 + INTERP_16_MASK_SHIFT_2_4(p2)) / 16);
110 }
111
112 static inline uint16 hq2x_interp_16_97(uint16 p1, uint16 p2)
113 {
114     return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*9 + INTERP_16_MASK_1_3(p2)*7) / 16)
115         | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*9 + INTERP_16_MASK_SHIFT_2_4(p2)*7) / 16);
116 }
117
118 #define INTERP_32_MASK_1_3(v) ((v)&0x00FF00FF)
119 #define INTERP_32_MASK_SHIFT_2_4(v) (((v)&0xFF00FF00)>>8)
120 #define INTERP_32_MASK_SHIFTBACK_2_4(v) (((INTERP_32_MASK_1_3(v))<<8))
121
122 static inline uint32 hq2x_interp_32_521(uint32 p1, uint32 p2, uint32 p3)
123 {
124     return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*5 + INTERP_32_MASK_1_3(p2)*2 + INTERP_32_MASK_1_3(p3)*1) / 8)
125         | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*5 + INTERP_32_MASK_SHIFT_2_4(p2)*2 + INTERP_32_MASK_SHIFT_2_4(p3)*1) / 8);
126 }
127
128 static inline uint32 hq2x_interp_32_332(uint32 p1, uint32 p2, uint32 p3)
129 {
130     return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*3 + INTERP_32_MASK_1_3(p2)*3 + INTERP_32_MASK_1_3(p3)*2) / 8)
131         | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*3 + INTERP_32_MASK_SHIFT_2_4(p2)*3 + INTERP_32_MASK_SHIFT_2_4(p3)*2) / 8);
132 }
133
134 static inline uint32 hq2x_interp_32_211(uint32 p1, uint32 p2, uint32 p3)
135 {
136     return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*2 + INTERP_32_MASK_1_3(p2) + INTERP_32_MASK_1_3(p3)) / 4)
137         | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*2 + INTERP_32_MASK_SHIFT_2_4(p2) + INTERP_32_MASK_SHIFT_2_4(p3)) / 4);
138 }
139
140 static inline uint32 hq2x_interp_32_611(uint32 p1, uint32 p2, uint32 p3)
141 {
142     return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*6 + INTERP_32_MASK_1_3(p2) + INTERP_32_MASK_1_3(p3)) / 8)
143         | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*6 + INTERP_32_MASK_SHIFT_2_4(p2) + INTERP_32_MASK_SHIFT_2_4(p3)) / 8);
144 }
145
146 static inline uint32 hq2x_interp_32_71(uint32 p1, uint32 p2)
147 {
148     return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*7 + INTERP_32_MASK_1_3(p2)) / 8)
149         | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*7 + INTERP_32_MASK_SHIFT_2_4(p2)) / 8);
150 }
151
152 static inline uint32 hq2x_interp_32_772(uint32 p1, uint32 p2, uint32 p3)
153 {
154     return INTERP_32_MASK_1_3(((INTERP_32_MASK_1_3(p1) + INTERP_32_MASK_1_3(p2))*7 + INTERP_32_MASK_1_3(p3)*2) / 16)
155         | INTERP_32_MASK_SHIFTBACK_2_4(((INTERP_32_MASK_SHIFT_2_4(p1) + INTERP_32_MASK_SHIFT_2_4(p2))*7 + INTERP_32_MASK_SHIFT_2_4(p3)*2) / 16);
156 }
157
158 static inline uint32 hq2x_interp_32_11(uint32 p1, uint32 p2)
159 {
160     return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1) + INTERP_32_MASK_1_3(p2)) / 2)
161         | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1) + INTERP_32_MASK_SHIFT_2_4(p2)) / 2);
162 }
163
164 static inline uint32 hq2x_interp_32_31(uint32 p1, uint32 p2)
165 {
166     return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*3 + INTERP_32_MASK_1_3(p2)) / 4)
167         | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*3 + INTERP_32_MASK_SHIFT_2_4(p2)) / 4);
168 }
169
170 static inline uint32 hq2x_interp_32_1411(uint32 p1, uint32 p2, uint32 p3)
171 {
172     return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*14 + INTERP_32_MASK_1_3(p2) + INTERP_32_MASK_1_3(p3)) / 16)
173         | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*14 + INTERP_32_MASK_SHIFT_2_4(p2) + INTERP_32_MASK_SHIFT_2_4(p3)) / 16);
174 }
175
176 static inline uint32 hq2x_interp_32_431(uint32 p1, uint32 p2, uint32 p3)
177 {
178     return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*4 + INTERP_32_MASK_1_3(p2)*3 + INTERP_32_MASK_1_3(p3)) / 8)
179         | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*4 + INTERP_32_MASK_SHIFT_2_4(p2)*3 + INTERP_32_MASK_SHIFT_2_4(p3)) / 8);
180 }
181
182 static inline uint32 hq2x_interp_32_53(uint32 p1, uint32 p2)
183 {
184     return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*5 + INTERP_32_MASK_1_3(p2)*3) / 8)
185         | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*5 + INTERP_32_MASK_SHIFT_2_4(p2)*3) / 8);
186 }
187
188 static inline uint32 hq2x_interp_32_151(uint32 p1, uint32 p2)
189 {
190     return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*15 + INTERP_32_MASK_1_3(p2)) / 16)
191         | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*15 + INTERP_32_MASK_SHIFT_2_4(p2)) / 16);
192 }
193
194 static inline uint32 hq2x_interp_32_97(uint32 p1, uint32 p2)
195 {
196     return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*9 + INTERP_32_MASK_1_3(p2)*7) / 16)
197         | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*9 + INTERP_32_MASK_SHIFT_2_4(p2)*7) / 16);
198 }
199
200 /***************************************************************************/
201 /* diff */
202
203 #define INTERP_Y_LIMIT (0x30*4)
204 #define INTERP_U_LIMIT (0x07*4)
205 #define INTERP_V_LIMIT (0x06*8)
206
207 static int hq2x_interp_16_diff(uint16 p1, uint16 p2)
208 {
209     int r, g, b;
210     int y, u, v;
211
212     if (p1 == p2)
213         return 0;
214
215     b = (int)((p1 & 0x000F) - (p2 & 0x000F));
216     g = (int)((p1 & 0x00F0) - (p2 & 0x00F0)) >> 4;
217     r = (int)((p1 & 0x0F00) - (p2 & 0x0F00)) >> 8;
218
219     y = r + g + b;
220     u = r - b;
221     v = -r + 2*g - b;
222
223     if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
224         return 1;
225
226     if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
227         return 1;
228
229     if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
230         return 1;
231
232     return 0;
233 }
234
235 static int hq2x_interp_32_diff(uint32 p1, uint32 p2)
236 {
237     int r, g, b;
238     int y, u, v;
239
240     if ((p1 & 0xF8F8F8) == (p2 & 0xF8F8F8))
241         return 0;
242
243     b = (int)((p1 & 0xFF) - (p2 & 0xFF));
244     g = (int)((p1 & 0xFF00) - (p2 & 0xFF00)) >> 8;
245     r = (int)((p1 & 0xFF0000) - (p2 & 0xFF0000)) >> 16;
246
247     y = r + g + b;
248     u = r - b;
249     v = -r + 2*g - b;
250
251     if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
252         return 1;
253
254     if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
255         return 1;
256
257     if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
258         return 1;
259
260     return 0;
261 }
262
263 static void interp_set(unsigned bits_per_pixel)
264 {
265     interp_bits_per_pixel = bits_per_pixel;
266 }
267
268
269 static void hq2x_16_def(uint16* dst0, uint16* dst1, const uint16* src0, const uint16* src1, const uint16* src2, unsigned count)
270 {
271     unsigned i;
272
273     for(i=0;i<count;++i) {
274         unsigned char mask;
275
276         uint16 c[9];
277
278         c[1] = src0[0];
279         c[4] = src1[0];
280         c[7] = src2[0];
281
282         if (i>0) {
283             c[0] = src0[-1];
284             c[3] = src1[-1];
285             c[6] = src2[-1];
286         } else {
287             c[0] = c[1];
288             c[3] = c[4];
289             c[6] = c[7];
290         }
291
292         if (i<count-1) {
293             c[2] = src0[1];
294             c[5] = src1[1];
295             c[8] = src2[1];
296         } else {
297             c[2] = c[1];
298             c[5] = c[4];
299             c[8] = c[7];
300         }
301
302         mask = 0;
303
304         if (hq2x_interp_16_diff(c[0], c[4]))
305             mask |= 1 << 0;
306         if (hq2x_interp_16_diff(c[1], c[4]))
307             mask |= 1 << 1;
308         if (hq2x_interp_16_diff(c[2], c[4]))
309             mask |= 1 << 2;
310         if (hq2x_interp_16_diff(c[3], c[4]))
311             mask |= 1 << 3;
312         if (hq2x_interp_16_diff(c[5], c[4]))
313             mask |= 1 << 4;
314         if (hq2x_interp_16_diff(c[6], c[4]))
315             mask |= 1 << 5;
316         if (hq2x_interp_16_diff(c[7], c[4]))
317             mask |= 1 << 6;
318         if (hq2x_interp_16_diff(c[8], c[4]))
319             mask |= 1 << 7;
320
321 #define P0 dst0[0]
322 #define P1 dst0[1]
323 #define P2 dst1[0]
324 #define P3 dst1[1]
325 #define HQ2X_MUR hq2x_interp_16_diff(c[1], c[5])
326 #define HQ2X_MDR hq2x_interp_16_diff(c[5], c[7])
327 #define HQ2X_MDL hq2x_interp_16_diff(c[7], c[3])
328 #define HQ2X_MUL hq2x_interp_16_diff(c[3], c[1])
329 #define IC(p0) c[p0]
330 #define I11(p0,p1) hq2x_interp_16_11(c[p0], c[p1])
331 #define I211(p0,p1,p2) hq2x_interp_16_211(c[p0], c[p1], c[p2])
332 #define I31(p0,p1) hq2x_interp_16_31(c[p0], c[p1])
333 #define I332(p0,p1,p2) hq2x_interp_16_332(c[p0], c[p1], c[p2])
334 #define I431(p0,p1,p2) hq2x_interp_16_431(c[p0], c[p1], c[p2])
335 #define I521(p0,p1,p2) hq2x_interp_16_521(c[p0], c[p1], c[p2])
336 #define I53(p0,p1) hq2x_interp_16_53(c[p0], c[p1])
337 #define I611(p0,p1,p2) hq2x_interp_16_611(c[p0], c[p1], c[p2])
338 #define I71(p0,p1) hq2x_interp_16_71(c[p0], c[p1])
339 #define I772(p0,p1,p2) hq2x_interp_16_772(c[p0], c[p1], c[p2])
340 #define I97(p0,p1) hq2x_interp_16_97(c[p0], c[p1])
341 #define I1411(p0,p1,p2) hq2x_interp_16_1411(c[p0], c[p1], c[p2])
342 #define I151(p0,p1) hq2x_interp_16_151(c[p0], c[p1])
343
344         switch (mask) {
345 #include "TextureFilters_hq2x.h"
346         }
347
348 #undef P0
349 #undef P1
350 #undef P2
351 #undef P3
352 #undef HQ2X_MUR
353 #undef HQ2X_MDR
354 #undef HQ2X_MDL
355 #undef HQ2X_MUL
356 #undef IC
357 #undef I11
358 #undef I211
359 #undef I31
360 #undef I332
361 #undef I431
362 #undef I521
363 #undef I53
364 #undef I611
365 #undef I71
366 #undef I772
367 #undef I97
368 #undef I1411
369 #undef I151
370
371         src0 += 1;
372         src1 += 1;
373         src2 += 1;
374         dst0 += 2;
375         dst1 += 2;
376     }
377 }
378
379 static void hq2x_32_def(uint32* dst0, uint32* dst1, const uint32* src0, const uint32* src1, const uint32* src2, unsigned count)
380 {
381     unsigned i;
382
383     for(i=0;i<count;++i) {
384         unsigned char mask;
385
386         uint32 c[9];
387
388         c[1] = src0[0];
389         c[4] = src1[0];
390         c[7] = src2[0];
391
392         if (i>0) {
393             c[0] = src0[-1];
394             c[3] = src1[-1];
395             c[6] = src2[-1];
396         } else {
397             c[0] = src0[0];
398             c[3] = src1[0];
399             c[6] = src2[0];
400         }
401
402         if (i<count-1) {
403             c[2] = src0[1];
404             c[5] = src1[1];
405             c[8] = src2[1];
406         } else {
407             c[2] = src0[0];
408             c[5] = src1[0];
409             c[8] = src2[0];
410         }
411
412         mask = 0;
413
414         if (hq2x_interp_32_diff(c[0], c[4]))
415             mask |= 1 << 0;
416         if (hq2x_interp_32_diff(c[1], c[4]))
417             mask |= 1 << 1;
418         if (hq2x_interp_32_diff(c[2], c[4]))
419             mask |= 1 << 2;
420         if (hq2x_interp_32_diff(c[3], c[4]))
421             mask |= 1 << 3;
422         if (hq2x_interp_32_diff(c[5], c[4]))
423             mask |= 1 << 4;
424         if (hq2x_interp_32_diff(c[6], c[4]))
425             mask |= 1 << 5;
426         if (hq2x_interp_32_diff(c[7], c[4]))
427             mask |= 1 << 6;
428         if (hq2x_interp_32_diff(c[8], c[4]))
429             mask |= 1 << 7;
430
431 #define P0 dst0[0]
432 #define P1 dst0[1]
433 #define P2 dst1[0]
434 #define P3 dst1[1]
435 #define HQ2X_MUR hq2x_interp_32_diff(c[1], c[5])
436 #define HQ2X_MDR hq2x_interp_32_diff(c[5], c[7])
437 #define HQ2X_MDL hq2x_interp_32_diff(c[7], c[3])
438 #define HQ2X_MUL hq2x_interp_32_diff(c[3], c[1])
439 #define IC(p0) c[p0]
440 #define I11(p0,p1) hq2x_interp_32_11(c[p0], c[p1])
441 #define I211(p0,p1,p2) hq2x_interp_32_211(c[p0], c[p1], c[p2])
442 #define I31(p0,p1) hq2x_interp_32_31(c[p0], c[p1])
443 #define I332(p0,p1,p2) hq2x_interp_32_332(c[p0], c[p1], c[p2])
444 #define I431(p0,p1,p2) hq2x_interp_32_431(c[p0], c[p1], c[p2])
445 #define I521(p0,p1,p2) hq2x_interp_32_521(c[p0], c[p1], c[p2])
446 #define I53(p0,p1) hq2x_interp_32_53(c[p0], c[p1])
447 #define I611(p0,p1,p2) hq2x_interp_32_611(c[p0], c[p1], c[p2])
448 #define I71(p0,p1) hq2x_interp_32_71(c[p0], c[p1])
449 #define I772(p0,p1,p2) hq2x_interp_32_772(c[p0], c[p1], c[p2])
450 #define I97(p0,p1) hq2x_interp_32_97(c[p0], c[p1])
451 #define I1411(p0,p1,p2) hq2x_interp_32_1411(c[p0], c[p1], c[p2])
452 #define I151(p0,p1) hq2x_interp_32_151(c[p0], c[p1])
453
454         switch (mask) {
455 #include "TextureFilters_hq2x.h"
456         }
457
458 #undef P0
459 #undef P1
460 #undef P2
461 #undef P3
462 #undef HQ2X_MUR
463 #undef HQ2X_MDR
464 #undef HQ2X_MDL
465 #undef HQ2X_MUL
466 #undef IC
467 #undef I11
468 #undef I211
469 #undef I31
470 #undef I332
471 #undef I431
472 #undef I521
473 #undef I53
474 #undef I611
475 #undef I71
476 #undef I772
477 #undef I97
478 #undef I1411
479 #undef I151
480
481         src0 += 1;
482         src1 += 1;
483         src2 += 1;
484         dst0 += 2;
485         dst1 += 2;
486     }
487 }
488
489 /***************************************************************************/
490 /* LQ2x C implementation */
491
492 /*
493 * This effect is derived from the hq2x effect made by Maxim Stepin
494 */
495
496 static void lq2x_16_def(uint16* dst0, uint16* dst1, const uint16* src0, const uint16* src1, const uint16* src2, unsigned count)
497 {
498     unsigned i;
499
500     for(i=0;i<count;++i) {
501         unsigned char mask;
502
503         uint16 c[9];
504
505         c[1] = src0[0];
506         c[4] = src1[0];
507         c[7] = src2[0];
508
509         if (i>0) {
510             c[0] = src0[-1];
511             c[3] = src1[-1];
512             c[6] = src2[-1];
513         } else {
514             c[0] = c[1];
515             c[3] = c[4];
516             c[6] = c[7];
517         }
518
519         if (i<count-1) {
520             c[2] = src0[1];
521             c[5] = src1[1];
522             c[8] = src2[1];
523         } else {
524             c[2] = c[1];
525             c[5] = c[4];
526             c[8] = c[7];
527         }
528
529         mask = 0;
530
531         if (c[0] != c[4])
532             mask |= 1 << 0;
533         if (c[1] != c[4])
534             mask |= 1 << 1;
535         if (c[2] != c[4])
536             mask |= 1 << 2;
537         if (c[3] != c[4])
538             mask |= 1 << 3;
539         if (c[5] != c[4])
540             mask |= 1 << 4;
541         if (c[6] != c[4])
542             mask |= 1 << 5;
543         if (c[7] != c[4])
544             mask |= 1 << 6;
545         if (c[8] != c[4])
546             mask |= 1 << 7;
547
548 #define P0 dst0[0]
549 #define P1 dst0[1]
550 #define P2 dst1[0]
551 #define P3 dst1[1]
552 #define HQ2X_MUR (c[1] != c[5])
553 #define HQ2X_MDR (c[5] != c[7])
554 #define HQ2X_MDL (c[7] != c[3])
555 #define HQ2X_MUL (c[3] != c[1])
556 #define IC(p0) c[p0]
557 #define I11(p0,p1) hq2x_interp_16_11(c[p0], c[p1])
558 #define I211(p0,p1,p2) hq2x_interp_16_211(c[p0], c[p1], c[p2])
559 #define I31(p0,p1) hq2x_interp_16_31(c[p0], c[p1])
560 #define I332(p0,p1,p2) hq2x_interp_16_332(c[p0], c[p1], c[p2])
561 #define I431(p0,p1,p2) hq2x_interp_16_431(c[p0], c[p1], c[p2])
562 #define I521(p0,p1,p2) hq2x_interp_16_521(c[p0], c[p1], c[p2])
563 #define I53(p0,p1) hq2x_interp_16_53(c[p0], c[p1])
564 #define I611(p0,p1,p2) hq2x_interp_16_611(c[p0], c[p1], c[p2])
565 #define I71(p0,p1) hq2x_interp_16_71(c[p0], c[p1])
566 #define I772(p0,p1,p2) hq2x_interp_16_772(c[p0], c[p1], c[p2])
567 #define I97(p0,p1) hq2x_interp_16_97(c[p0], c[p1])
568 #define I1411(p0,p1,p2) hq2x_interp_16_1411(c[p0], c[p1], c[p2])
569 #define I151(p0,p1) hq2x_interp_16_151(c[p0], c[p1])
570
571         switch (mask) {
572 #include "TextureFilters_lq2x.h"
573         }
574
575 #undef P0
576 #undef P1
577 #undef P2
578 #undef P3
579 #undef HQ2X_MUR
580 #undef HQ2X_MDR
581 #undef HQ2X_MDL
582 #undef HQ2X_MUL
583 #undef IC
584 #undef I11
585 #undef I211
586 #undef I31
587 #undef I332
588 #undef I431
589 #undef I521
590 #undef I53
591 #undef I611
592 #undef I71
593 #undef I772
594 #undef I97
595 #undef I1411
596 #undef I151
597
598         src0 += 1;
599         src1 += 1;
600         src2 += 1;
601         dst0 += 2;
602         dst1 += 2;
603     }
604 }
605
606 static void lq2x_32_def(uint32* dst0, uint32* dst1, const uint32* src0, const uint32* src1, const uint32* src2, unsigned count)
607 {
608     unsigned i;
609
610     for(i=0;i<count;++i) {
611         unsigned char mask;
612
613         uint32 c[9];
614
615         c[1] = src0[0];
616         c[4] = src1[0];
617         c[7] = src2[0];
618
619         if (i>0) {
620             c[0] = src0[-1];
621             c[3] = src1[-1];
622             c[6] = src2[-1];
623         } else {
624             c[0] = c[1];
625             c[3] = c[4];
626             c[6] = c[7];
627         }
628
629         if (i<count-1) {
630             c[2] = src0[1];
631             c[5] = src1[1];
632             c[8] = src2[1];
633         } else {
634             c[2] = c[1];
635             c[5] = c[4];
636             c[8] = c[7];
637         }
638
639         mask = 0;
640
641         if (c[0] != c[4])
642             mask |= 1 << 0;
643         if (c[1] != c[4])
644             mask |= 1 << 1;
645         if (c[2] != c[4])
646             mask |= 1 << 2;
647         if (c[3] != c[4])
648             mask |= 1 << 3;
649         if (c[5] != c[4])
650             mask |= 1 << 4;
651         if (c[6] != c[4])
652             mask |= 1 << 5;
653         if (c[7] != c[4])
654             mask |= 1 << 6;
655         if (c[8] != c[4])
656             mask |= 1 << 7;
657
658 #define P0 dst0[0]
659 #define P1 dst0[1]
660 #define P2 dst1[0]
661 #define P3 dst1[1]
662 #define HQ2X_MUR (c[1] != c[5])
663 #define HQ2X_MDR (c[5] != c[7])
664 #define HQ2X_MDL (c[7] != c[3])
665 #define HQ2X_MUL (c[3] != c[1])
666 #define IC(p0) c[p0]
667 #define I11(p0,p1) hq2x_interp_32_11(c[p0], c[p1])
668 #define I211(p0,p1,p2) hq2x_interp_32_211(c[p0], c[p1], c[p2])
669 #define I31(p0,p1) hq2x_interp_32_31(c[p0], c[p1])
670 #define I332(p0,p1,p2) hq2x_interp_32_332(c[p0], c[p1], c[p2])
671 #define I431(p0,p1,p2) hq2x_interp_32_431(c[p0], c[p1], c[p2])
672 #define I521(p0,p1,p2) hq2x_interp_32_521(c[p0], c[p1], c[p2])
673 #define I53(p0,p1) hq2x_interp_32_53(c[p0], c[p1])
674 #define I611(p0,p1,p2) hq2x_interp_32_611(c[p0], c[p1], c[p2])
675 #define I71(p0,p1) hq2x_interp_32_71(c[p0], c[p1])
676 #define I772(p0,p1,p2) hq2x_interp_32_772(c[p0], c[p1], c[p2])
677 #define I97(p0,p1) hq2x_interp_32_97(c[p0], c[p1])
678 #define I1411(p0,p1,p2) hq2x_interp_32_1411(c[p0], c[p1], c[p2])
679 #define I151(p0,p1) hq2x_interp_32_151(c[p0], c[p1])
680
681         switch (mask) {
682 #include "TextureFilters_lq2x.h"
683         }
684
685 #undef P0
686 #undef P1
687 #undef P2
688 #undef P3
689 #undef HQ2X_MUR
690 #undef HQ2X_MDR
691 #undef HQ2X_MDL
692 #undef HQ2X_MUL
693 #undef IC
694 #undef I11
695 #undef I211
696 #undef I31
697 #undef I332
698 #undef I431
699 #undef I521
700 #undef I53
701 #undef I611
702 #undef I71
703 #undef I772
704 #undef I97
705 #undef I1411
706 #undef I151
707
708         src0 += 1;
709         src1 += 1;
710         src2 += 1;
711         dst0 += 2;
712         dst1 += 2;
713     }
714 }
715
716 void hq2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
717 {
718     uint16 *dst0 = (uint16 *)dstPtr;
719     uint16 *dst1 = dst0 + (dstPitch >> 1);
720
721     uint16 *src0 = (uint16 *)srcPtr;
722     uint16 *src1 = src0 + (srcPitch >> 1);
723     uint16 *src2 = src1 + (srcPitch >> 1);
724
725     hq2x_16_def(dst0, dst1, src0, src0, src1, width);
726     if( height == 1 ) return;
727
728     int count = height;
729
730     count -= 2;
731     while(count>0) {
732         dst0 += dstPitch;
733         dst1 += dstPitch;
734         hq2x_16_def(dst0, dst1, src0, src1, src2, width);
735         src0 = src1;
736         src1 = src2;
737         src2 += srcPitch >> 1;
738         --count;
739     }
740     dst0 += dstPitch;
741     dst1 += dstPitch;
742     hq2x_16_def(dst0, dst1, src0, src1, src1, width);
743 }
744
745 void hq2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
746 {
747     uint32 *dst0 = (uint32 *)dstPtr;
748     uint32 *dst1 = dst0 + (dstPitch >> 2);
749
750     uint32 *src0 = (uint32 *)srcPtr;
751     uint32 *src1 = src0 + (srcPitch >> 2);
752     uint32 *src2 = src1 + (srcPitch >> 2);
753     hq2x_32_def(dst0, dst1, src0, src0, src1, width);
754     if( height == 1 ) return;
755
756     int count = height;
757
758     count -= 2;
759     while(count>0) {
760         dst0 += dstPitch >> 1;
761         dst1 += dstPitch >> 1;
762         hq2x_32_def(dst0, dst1, src0, src1, src2, width);
763         src0 = src1;
764         src1 = src2;
765         src2 += srcPitch >> 2;
766         --count;
767     }
768     dst0 += dstPitch >> 1;
769     dst1 += dstPitch >> 1;
770     hq2x_32_def(dst0, dst1, src0, src1, src1, width);
771 }
772
773 void lq2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
774 {
775     uint16 *dst0 = (uint16 *)dstPtr;
776     uint16 *dst1 = dst0 + (dstPitch >> 1);
777
778     uint16 *src0 = (uint16 *)srcPtr;
779     uint16 *src1 = src0 + (srcPitch >> 1);
780     uint16 *src2 = src1 + (srcPitch >> 1);
781
782     lq2x_16_def(dst0, dst1, src0, src0, src1, width);
783     if( height == 1 ) return;
784
785     int count = height;
786
787     count -= 2;
788     while(count>0) {
789         dst0 += dstPitch;
790         dst1 += dstPitch;
791         hq2x_16_def(dst0, dst1, src0, src1, src2, width);
792         src0 = src1;
793         src1 = src2;
794         src2 += srcPitch >> 1;
795         --count;
796     }
797     dst0 += dstPitch;
798     dst1 += dstPitch;
799     lq2x_16_def(dst0, dst1, src0, src1, src1, width);
800 }
801
802 void lq2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
803 {
804     uint32 *dst0 = (uint32 *)dstPtr;
805     uint32 *dst1 = dst0 + (dstPitch >> 2);
806
807     uint32 *src0 = (uint32 *)srcPtr;
808     uint32 *src1 = src0 + (srcPitch >> 2);
809     uint32 *src2 = src1 + (srcPitch >> 2);
810     lq2x_32_def(dst0, dst1, src0, src0, src1, width);
811     if( height == 1 ) return;
812
813     int count = height;
814
815     count -= 2;
816     while(count>0) {
817         dst0 += dstPitch >> 1;
818         dst1 += dstPitch >> 1;
819         hq2x_32_def(dst0, dst1, src0, src1, src2, width);
820         src0 = src1;
821         src1 = src2;
822         src2 += srcPitch >> 2;
823         --count;
824     }
825     dst0 += dstPitch >> 1;
826     dst1 += dstPitch >> 1;
827     lq2x_32_def(dst0, dst1, src0, src1, src1, width);
828 }
829
830 void hq2x_init(unsigned bits_per_pixel)
831 {
832     interp_set(bits_per_pixel);
833 }
834
835 /************************************************************************/
836 /* hq3x filters                                                         */
837 /************************************************************************/
838
839 /************************************************************************/
840 /* scale2x filters                                                      */
841 /************************************************************************/
842
843 /************************************************************************/
844 /* scale3x filters                                                      */
845 /************************************************************************/
846